У меня есть viewmodel, который состоит из списка (foreach loop) DoctorPrices, и при нажатии на элемент в списке он открывает форму CRUD сбоку. Однако, когда я обновляю значения на CRUD, наблюдаемый массив, привязанный к foreach, не освежает? (хотя значения обновляются в БД правильно)breeze observableArray binding - можно ли наблюдать свойства?
Из моего модуля доступа к данным я вызываю следующий запрос.
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
return manager.executeQueryLocally(query);
}
В моей ViewModel у меня есть следующий код:
this.services = ko.computed(function() {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});
услуги привязывается с помощью цикла Еогеасп (не размещения здесь код прост и работает)
Когда я нажмите на одну из Докторов, чтобы получить данные следующим образом:
this.selectedPrice = function (data, event) {
self.currentService(data);
self.showEdit(true);
};
Затем я привязываю selectPrice к простой форме, у которой свойства на ней должны быть изменены пользователем. Затем я вызываю manager.SaveChanges().
В результате возникает следующая проблема: значение обновляется правильно, но список GUI/Original, связанный в foreach, не обновляется? Являются ли свойства на ветру не наблюдаемыми? Каков наилучший способ работы с чем-то подобным.
Я думал, обходной путь и изменения кода, с чем-то вроде этого:
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
});
Но я чувствую, что очистка массива в том, как это неаккуратно и не правильный способ делать вещи, особенно с длинными списками.
Может ли кто-нибудь указать мне в правильном направлении, как правильно привязать свойства observableArray, чтобы они были обновлены?
Дополнительный код мой ВМ компонент:
function services() {
var self = this;
this.showForm = ko.observable(false);
this.currentService = ko.observable();
this.services = ko.observableArray(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
this.title = ko.observable();
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
self.showDetails(false);
});
this.show = function (value) {
self.showForm(value);
};
this.showDetails = ko.observable(false);
this.addNewService = function() {
self.currentService(doctorServices.createService(doctorList.viewModel.instance.currentDoctorID()));
console.log(self.currentService().entityAspect.entityState);
self.showDetails(true);
};
this.showDelete = ko.computed(function() {
if (self.currentService() == null)
return false;
else if (self.currentService().entityAspect.entityState.isDetached()) {
self.title('Add new service');
return false;
} else {
self.title('Edit service');
return true;
}
});
this.deleteService = function() {
self.currentService().entityAspect.setDeleted();
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
};
this.closeDetails = function() {
doctorServices.manager.rejectChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.showDetails(false);
};
this.selectService = function (data, event) {
self.currentService(data);
self.showDetails(true);
};
this.saveChanges = function() {
console.log(self.currentService().entityAspect.entityState);
if (self.currentService().entityAspect.entityState.isDetached()) {
doctorServices.attachEntity(self.currentService());
}
console.log(self.currentService().entityAspect.entityState);
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.currentService.notifySubscribers();
self.showDetails(true);
};
}
return {
viewModel: {
instance: new services()
},
template: servicesTemplate,
};
Ниже мой Бриз данных Класс:
define('data/doctorServices', ['jquery', 'data/dataManager', 'knockout','mod/medappBase', 'breeze', 'breeze.savequeuing'], function ($, manager, ko,base, breeze, savequeuing) {
var services = ko.observableArray([]);
return {
attachEntity:attachEntity,
getServices: getServices,
services: services,
manager:manager,
getDoctorServices: getDoctorServices,
getServiceById: getServiceById,
createService:createService,
hasChanges: hasChanges,
saveChanges: saveChanges
};
function getServices() {
var query = breeze.EntityQuery.from("DoctorPrices");
return manager.executeQuery(query).then(function (data) {
services(data.results);
}).fail(function (data) {
console.log('fetch failed...');
console.log(data);
});;
}
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
var set = manager.executeQueryLocally(query);
return set;
}
function getServiceById(serviceId) {
return manager.createEntity('DoctorPrice', serviceId);
//return manager.getEntityByKey('DoctorPrice', serviceId);
}
function handleSaveValidationError(error) {
var message = "Not saved due to validation error";
try { // fish out the first error
var firstErr = error.innerError.entityErrors[0];
message += ": " + firstErr.errorMessage;
base.addNotify('error', 'Could not save.', message);
} catch (e) { /* eat it for now */ }
return message;
}
function hasChanges() {
return manager.hasChanges();
}
function attachEntity(entity) {
manager.addEntity(entity);
}
function createService(doctorId) {
return manager.createEntity('DoctorPrice', { DoctorPricingID: breeze.core.getUuid(), DoctorID:doctorId }, breeze.EntityState.Detached);
};
function saveChanges() {
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
function saveSucceeded(saveResult) {
base.addNotify('success', 'Saved.', 'Your updates have been saved.');
}
function saveFailed(error) {
var reason = error.message;
var detail = error.detail;
if (error.innerError.entityErrors) {
reason = handleSaveValidationError(error);
} else if (detail && detail.ExceptionType &&
detail.ExceptionType.indexOf('OptimisticConcurrencyException') !== -1) {
// Concurrency error
reason =
"Another user, perhaps the server, " +
"may have deleted one or all of the settings." +
" You may have to restart the app.";
} else {
reason = "Failed to save changes: " + reason +
" You may have to restart the app.";
}
console.log(error);
console.log(reason);
}
}
});
Обратите внимание, что это моя попытка frist как для класса данных, так и для виртуальной машины. В настоящий момент я сильно полагаюсь на очистку массива ([]) и используя notifySubscribers, чтобы обновить массив :(
спасибо за быстрый ответ. его вычисляется, потому что currentDoctorID изменяется в выпадающем списке, который затем должен требовать/фильтровать бриз. Я обновил с наблюдаемыми определениями в верхней части - они верны или вывели бы ошибку. –
Спасибо, после всего, что сообщение, я думаю, я, возможно, нашел свою ошибку, как вы правильно указали, я объявляю сервис как наблюдаемый, а не наблюдаемый массив ... Поэтому я посмотрю на это и измените определение из: this. services = ko.observable() к this.services = ko.observableArray() !! Какая ошибка новобранец! (должно быть, была поздняя ночь!) –
Hi Ward. Я попытался напрасно снова, даже если я изменяю наблюдаемый массив, когда я манипулирую базовыми данными, список не обновляется - я думаю, мой вопрос в том, что я запускаю простой запрос и привязываю его к списку, если базовый кеш изменения (добавить новые записи и т. д.) будет автоматически обновляться список? или нужно ли требовать и повторно заполнить массив? –