@asdz

Как сделать связанные списки на knockout?

В модели два свойства связанных со списками:
ViewModel=function(){
self=this;
self.A=ko.observable();
self.B=ko.observable();
self.listA=ko.observableArray();
self.listB=ko.observableArray();
}

html:
<select data-bind="options: listA, optionsText: 'Value', value: A">
<select data-bind="options: listB, optionsText: 'Value', value: B">


Список listB зависит от значения в А. При изменении значения А пользователем, со стороны UI, список listB загружается с сервера с помощью getJSON:
self.A.subscribe(function(newValue) {
    $.getJSON({ url:"/loadB.php", data:newValue, function(data){
         //загружаем data в listB
       }  
    });   
});

Проблема возникает когда я загружаю модель с сервера, допустим я получил
{
A: {Id:1,Value:"A"},
B: {Id:4,Value:1},
}

при установке
myViewModel.A(data.A);// тут начнет выполнятся аякс получения списка listB
myViewModel.B(data.B);

то значение в списке B будет равно не тому что я получил с сервера, а первому элементу из listB, т.к. в функции наблюдателе за A список listB будет очищен и повторно заполнен, естественно B при этом потеряется.
Как один из вариантов решения я использовал следующее:
self.A.subscribe(function(newValue) {
    $.getJSON({ url:"/loadB.php", data:newValue, function(data){
         var prevB=self.B() //запомним текущее значение B
         //загружаем data в listB
         //после загрузки, найдем в listB то значение что в prevB по ключу
         var matchValue= ko.utils.arrayFirst(self.listB, function (item) {
                    return prevB.Id == item.Id;
          });
         self.B(matchValue);
  }
});

Интересует, насколько грамотен такой способ и какие есть варианты решения этой задачи.
  • Вопрос задан
  • 2474 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы