2014-09-05 3 views
0

У меня есть модель представления, содержащая ссылку на другой объект, и связанный объект привязан к моему пользовательскому интерфейсу. Связывание, кажется, отлично работает, когда я добавляю объекты в наблюдаемый массив, но, похоже, не обновляюсь, когда я очищаю массив.Knockout js binding not update

Я воспроизвел проблему jsfiddle, и мне интересно, может ли кто-нибудь указать мне в правильном направлении?

http://jsfiddle.net/chriswnichols/gcywcce7/

function County(name) { 
    this.Name = name; 
} 

function ListCriteria() { 
    var self = this; 
    self.States = ko.observableArray([]); 
    self.Counties = ko.observableArray([]); 
    self.Zips = ko.observableArray([]); 
    self.Cities = ko.observableArray([]); 
    self.DobRanges = ko.observableArray([]); 
    self.Clear = function() { 
     self.States = ko.observableArray([]); 
     self.Counties = ko.observableArray([]); 
     self.Zips = ko.observableArray([]); 
     self.Cities = ko.observableArray([]); 
     self.DobRanges = ko.observableArray([]); 
    }; 
} 

var ViewModel = function() { 
    var listCriteria = new ListCriteria(), 
     reset = ko.computed(function() { 
      listCriteria.Clear(); 
     }); 
    return { 
     listCriteria: listCriteria, 
     reset: reset 
    } 
}; 
viewModel = new ViewModel(); 
ko.applyBindings(viewModel); 

Спасибо.

ответ

2

Это не работает, потому что новый создаются наблюдаемые массивы. KO связывает за наблюдаемый, поэтому старые наблюдаемые массивы все еще связаны - новые (несвязанные) наблюдаемые массивы не могут повлиять на пользовательский интерфейс.

Один из подходов состоит в том, чтобы вымыть оригинал наблюдаемые массивы. В этом случае, что может быть сделано с ObservableArray.removeAll:

self.Clear = function() { 
    [self.States, self.Counties, self.Zips].forEach(function (arr) { 
     arr.removeAll(); 
     // Alternative, because it updates the observable with an empty array 
     // (without creating a new unbound observable) 
     // arr([]); 
    }); 
}; 

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

var ViewModel = function() { 
    var listObs = ko.observable(new ListCriteria()); 
    return { 
     listCriteria: listObs, 
     // This probably shouldn't be a computed.. data-bind as "click: reset" 
     reset: function() { 
      // Assign a new value to existing (and bound) observable 
      listObs(new ListCriteria()); 
     } 
    } 
} 

И тогда это может быть с привязкой к данным в foreach: listCriteria().Counties. Тот же подход использования наблюдаемой косвенности также может быть выполнен на каждом массиве, а затем он будет выглядеть как foreach: listCriteria.States(), хотя в этом случае это глупо, учитывая, что он обертывает наблюдаемый массив.

function ListCriteria() { 
    var self = this; 
    self.States = ko.observable(ko.observableArray([])); 
    self.Clear = function() { 
     // Mutate existing observable, assigning an observable as a value 
     self.States(ko.observableArray([])); 
    }; 
} 

Однако решение этой проблемы является одинаковым во всех случаях: только использование мутации-наблюдаемых объектов влиять на связанные данные.

+0

'self.States = ko.observable (ko.observableArray ([]));' не является хорошим методом, внешний наблюдаемый не будет вести себя как массив и потребует двойной разворачивания. В качестве свойства используйте наблюдаемый массив. 'selfStates = ko.observableArray ([])'. – Tyrsius

+0

Это хороший момент; пример (признанный глупым) был включен для полноты, наряду с дополнительной разворачиванием требуемой привязки данных. – user2864740

+0

Я реализовал первый подход, и он отлично поработал. Благодарю. – user135498