[英]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>
我有兩個問題
self.isValid
不叫,當我做此vm.data()[0].valid = false;
? alert("Subscribe called!");
)? 我希望在我的代碼中兩次調用它。 謝謝
該代碼存在多個問題,但是與您所要求的內容有關的主要問題是,更改可觀察數組中的對象上的不可觀察屬性( valid
)不會更改可觀察數組,而只是更改可觀察數組上的一個屬性。對象。 因此自然沒有通知。 如果要通知,則需要監視valid
屬性(這意味着它必須是可觀察的)。
其他事宜:
淘汰賽的問題之一是,它有時會為您解包可觀察對象/計算對象,但是如果它們是表達式的一部分, 則不是這樣-您必須這樣做(使用()
):
<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
是可觀察/計算的時)。
您正在將self.isValid
設置為訂閱句柄 ,而不是已計算的訂閱句柄 ,因為您已過多地進行了鏈接。 :-)你需要完成呼叫結束后的分配computed
, 然后訂閱:
self.isValid = ko.computed(function() { // ... }, this); // <=== End the assignment here self.isValid.subscribe(function(newValue) { // ... }.bind(this));
您正在使用self = this
,但隨后也通過this
來computed
,並使用bind
與subscribe
。 這是無害的,但毫無意義。 一個或另一個就是您所需要的。
無需創建新的單獨對象作為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.