Одно начальное значение, которое вы загружаете
this.dongle = ko.observable($dongleData.attr('data-id'));
Это будет строковое значение "3". Где в качестве ключа выбора HTML-элемент фактически сохраняет / ожидает получить объект { "Id": "3", "Name": "dongle 3" }
.
Вот рабочая версия, которая получает правильные начальные значения и позволяет редактировать.
http://jsfiddle.net/madcapnmckay/28FVr/5/
Если вам нужно сохранить определенное значение, а не весь объект ключа / виджета, вы можете использовать атрибут optionsValue
для хранения только идентификатора. Вот так работает.
http://jsfiddle.net/madcapnmckay/VnjyT/4/
EDIT
Хорошо, у меня есть рабочая версия для вас. Я постараюсь обобщить все, что я изменил и почему.
http://jsfiddle.net/madcapnmckay/jXr8W/
Чтобы получить информацию о клиенте для работы
Имя клиента не было сохранено в ajaxCallGetProjectsByCustomer
json, поэтому при загрузке клиента не было возможности определить новое имя по полученным данным. Я добавил свойство Name каждому клиенту в json с именем «Название компании 1» и т. Д.
Чтобы заставить работать коллекцию проектов
Проблема здесь была, как было заявлено изначально с ключами. Вы инициализируете наблюдаемую selectedProject
с помощью $projectData.attr('data-id')
, что соответствует строковому значению 13. Это неверно, поскольку список выбора настроен таким образом, что он фактически сохраняет / ожидает получения самого объекта проекта. Изменение этого присвоения идентификатора на присвоение объекта сделало правильное начальное значение работы проекта.
var project = ko.utils.arrayFirst(customer.projects(), function(project){
return project.id == Number($projectData.attr('data-id'));
});
this.selectedProject = ko.observable(project);
К вашему сведению, в html произошла небольшая ошибка, для selectedProject.Name нужно было выбрать selectedProject (). Name. Ничего страшного.
Уверен, вы могли бы довольно легко это выяснить. Следующий бит - вот где настоящая проблема. Вы перезагружаете Клиента каждый раз, когда нажимаете кнопку редактирования. Это кажется странным, и вы можете пересмотреть этот подход.
Однако, что происходит, вы загружаете объект клиента с сервера по идентификатору. Присвойте его выбранному клиенту, это реально работает нормально. Но тогда, поскольку раскрывающийся список привязан к selectedCustomer().projects
и viewModel.selectedProject
, он ожидает, что selectedProject является членом selectedCustomer (). Projects. В случае объектов оператор равенства оценивает, совпадают ли ссылки, а в вашем случае - нет, потому что исходный selectedProject был уничтожен вместе с ассоциированным клиентом, когда вы перезаписали значение selectedCustomer. Тот факт, что идентификаторы одинаковы, не имеет значения.
Я решил взломать эту проблему.
var oldProjectId = viewModel.selectedProject().id;
viewModel.selectedCustomer(customer);
var sameProjectDifferentInstance = ko.utils.arrayFirst(customer.projects(), function(project){
return project.id == oldProjectId;
});
viewModel.selectedProject(sameProjectDifferentInstance || customer.projects()[0]);
Это сохраняет старый идентификатор проекта перед назначением нового клиента, ищет объект проекта в новом объекте клиента и присваивает его или по умолчанию первый, если не найден.
Я бы порекомендовал переосмыслить, когда вы загружаете объекты и как вы справляетесь с их жизненным циклом. Если вы храните текущие объекты в памяти с полным списком включенных проектов, вам не нужно загружать их для редактирования, просто отредактируйте и затем отправьте обновление обратно на сервер.
Возможно, вам будет проще хранить json с сервера в переменных js вместо элементов html dom. например,
<script>var projectInitialData = '@Model.ProjectInitialData.toJSON()';</script>
Надеюсь, это поможет.