簡體   English   中英

更改可觀察數組時不調用淘汰訂閱

[英]Knockout subscribe is not called when changing observable array

采取以下代碼:

 var koEvents = new ko.subscribable(); var viewModel = function() { var self = this; self.data = ko.observableArray([{ valid: true }, { valid: true }]); self.isValid = ko.computed(function() { var isValid = true; ko.utils.arrayForEach(self.data(), function(item) { console.log(item.valid); if (!item.valid) { isValid = false; return; }; }); return isValid; }, this).subscribe(function(newValue) { alert("Subscribe called!"); koEvents.notifySubscribers(newValue, "dataChanged"); }.bind(this)); return { data: self.data, isValid: self.isValid, }; } var vm = new viewModel(); ko.applyBindings(vm, document.getElementById("container")); vm.data()[0].valid = false; 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"> <div data-bind="text: isValid ? 'valid': 'invalid'"> </div> </div> 

我有兩個問題

  1. 為什么self.isValid不叫,當我做此vm.data()[0].valid = false;
  2. 為什么最初isValid為true,后來又設置為false,為什么沒有調用subscribe( alert("Subscribe called!"); )? 我希望在我的代碼中兩次調用它。

謝謝

該代碼存在多個問題,但是與您所要求的內容有關的主要問題是,更改可觀察數組中的對象上的不可觀察屬性( valid )不會更改可觀察數組,而只是更改可觀察數組上的一個屬性。對象。 因此自然沒有通知。 如果要通知,則需要監視valid屬性(這意味着它必須是可觀察的)。

其他事宜:

  1. 淘汰賽的問題之一是,它有時會為您解包可觀察對象/計算對象,但是如果它們是表達式的一部分, 則不是這樣-您必須這樣做(使用() ):

     <div data-bind="text: isValid() ? 'valid': 'invalid'"></div> <!-- ------------------------^^ --> 

    您的代碼正在測試isValid (不是isValid() )是否真實。 一直如此,因為它是一個函數引用。

    KO僅在標識符不是表達式的一部分時才為您自動展開。 例如,這有效:

     <!-- Works --> <div data-bind="visible: isValid">...</div> 

    但這不是:

     <!-- Doesn't work --> <div data-bind="visible: !isValid">...</div> 

    (當isValid是可觀察/計算的時)。

  2. 您正在將self.isValid設置為訂閱句柄 ,而不是已計算的訂閱句柄 ,因為您已過多地進行了鏈接。 :-)你需要完成呼叫結束后的分配computed然后訂閱:

     self.isValid = ko.computed(function() { // ... }, this); // <=== End the assignment here self.isValid.subscribe(function(newValue) { // ... }.bind(this)); 
  3. 您正在使用self = this ,但隨后也通過thiscomputed ,並使用bindsubscribe 這是無害的,但毫無意義。 一個或另一個就是您所需要的。

  4. 無需創建新的單獨對象作為VM構造函數的返回值。 您已經有一個對象(由new創建的對象)。

這是這些變化的示例。 第一個條目的valid屬性在800毫秒后設置為false

 var koEvents = new ko.subscribable(); var viewModel = function() { this.data = ko.observableArray([{ valid: ko.observable(true) }, { valid: ko.observable(true) }]); this.isValid = ko.computed(function() { var isValid = true; ko.utils.arrayForEach(this.data(), function(item) { console.log(item.valid()); if (!item.valid()) { isValid = false; return; }; }); return isValid; }, this); this.isValid.subscribe(function(newValue) { alert("Subscribe called!"); koEvents.notifySubscribers(newValue, "dataChanged"); }); } var vm = new viewModel(); ko.applyBindings(vm, document.getElementById("container")); setTimeout(function() { vm.data()[0].valid(false); }, 800); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"> <div data-bind="text: isValid() ? 'valid' : 'invalid'"></div> </div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM