2016-11-12 1 views
0

У меня есть модель KO с множеством вложенных объектов и коллекций вложенных объектов. Я использую параметры сопоставления ko.mappings, чтобы убедиться, что они правильно созданы во время создания модели, но значение очищается. Попытка начать с простого выпадающего меню и связывания объектов к нему:Отображение нокаутов: почему применяется привязка к ясным значениям из моих вложенных объектов?

<select id="myList" name="SelectedSurvey" id="SelectedSurvey" class="form-control" 
data-bind="options: AvailableSurveys, optionsText: 'Name', value: SelectedSurvey, 
optionsCaption: '-- Select Survey --'"></select> 

Затем, возьмите некоторые данные, при создании нового объекта на странице, он отлично работает, но при попытке изменить существующую запись из на той же странице выпадающее значение никогда не выбирается. Когда я проверяю viewModel.SelectedSurvey() the value is undefined, but it only becomes undefined after I call applyBindings() `. Почему это происходит? Как я могу это исправить?

Вот рабочий пример: http://jsfiddle.net/6wLcr52y/3/

Если открыть консоль и запустить его, вы увидите журнал до applyBindings() называется полной ViewModel, а вложенная объект SelectedSurvey() правильно komapping объекты, которые имеют значения , но затем после его вызова. SelectedSurvey() становится неопределенным, и поэтому мой раскрывающийся список никогда не имеет выбранного значения.

ответ

0

Параметр SelectedValue, похоже, не хочет принимать объект в качестве допустимого значения. Поэтому он очищает SelectedValue наблюдаемый, как только вы применяете привязки, думая, что не было предоставлено действительного значения.

В качестве обходного решения я создал решение, которое использует параметр optionsValue, чтобы принять свойство Id в качестве значения. Это позволит вам контролировать контроль над тем, какой опрос выбран, передавая просто значение «Id», а не весь объект Survey.

Для этого вам необходимо обновить версию нокаута до 3.4.0. Вы заблокированы для использования 2.2.1 по какой-либо причине?

Я также обновил ваш jsfiddle, чтобы включить более читаемую реализацию плагина сопоставления. Надеемся, что это будет исправить вашу проблему:

var ViewModel = function(data) { 
    var self = this; 
    self.AvailableSurveys = ko.mapping.fromJS(data.AvailableSurveys); 
    self.SelectedId = ko.observable(data.SelectedSurvey.Id); 
    self.SelectedSurvey = ko.pureComputed(function() { 
     for (i = 0; i < self.AvailableSurveys().length; i++) { 
      if (self.AvailableSurveys()[i].Id() === self.SelectedId()) { 
       return self.AvailableSurveys()[i]; 
      } 
     } 
    }) 
} 

Fiddle:http://jsfiddle.net/dw1284/v1L5tw6h/3/

+0

Это работает, но я очень разочарован тем, как ко/ko.mapping работы. Почему существует разница между функцией создания и редактирования в том, что вы сначала поставляете что-то со значением или нет. Я пытаюсь инициализировать эту проблему в любое время, когда есть вложенный объект или вложенный набор объектов. Например, проверьте эту скрипту: http://jsfiddle.net/6wLcr52y/6/. Метод subscribe не будет устанавливать выбранныйSurvey при загрузке, но если вы выберете его, изменив раскрывающийся список, он отлично работает и устанавливает все объект. – SventoryMang

+0

Думаю, я должен попросить разъяснить, когда использовать плагин сопоставления против нет, потому что вы используете как обычные наблюдаемые, так и ko.mapping.fromJS. Я думаю, эта часть меня пугает. В моем обычном опыте, когда вы работаете с вложенными объектами и добавляете к ним метод подписки, при редактировании записи я получаю сообщение об ошибке «SelectedSurvey is not a function». Если вложенный объект был подписан так же, как в моей оригинальной скрипке. Я думал, что это связано с тем, что плагин сопоставления не завершал его достаточно, и каждое свойство должно быть свойством сопоставления (путем его упаковки, чтобы оно имело свойство ko_mapping_). – SventoryMang

+0

Единственный раз, когда вам нужно будет использовать плагин отображения, всегда нужно, чтобы дочерние свойства были самими наблюдаемыми. Например, если вы намерены обновлять имена опроса «на лету» и хотите, чтобы эти обновленные имена отражались в графическом интерфейсе, вам понадобится плагин для создания вашего объекта self.AvailableSurveys. Причина, по которой я использовал обычную видимость для свойства self.SelectedId, состоит в том, что в поле Id нет дочерних элементов для преобразования в наблюдаемые, поэтому бессмысленно использовать плагин отображения. –

Смежные вопросы