簡體   English   中英

Knockout Computed Observable不更新UI

[英]Knockout Computed Observable not updating the UI

我遇到了一個問題,嘗試將knockoutJS observable 動態更新為計算的observable不會更新UI。

我已經在復選框上實現了父子依賴關系以下規則控制着交互。

  1. 選中“父復選框”后,將選中所有子復選框。
  2. 取消選中“父復選框”后,將取消選中所有子復選框。
  3. 如果未選中任何一個子復選框,則應取消選中父復選框。
  4. 選中所有子復選框后,應選中父復選框。

現在我有一個場景,其中父子依賴行為是動態的,即上述規則僅在用戶單擊按鈕時才開始工作。

我有一個實現,其中父復選框綁定到一個可觀察的屬性,然后該屬性被重寫為新的Computed Observable。 更改為Computed Observable后,前2個規則(規則1和2)有效,但最后2個規則(規則3和4)停止工作。 我可以在調試器中看到正確返回了返回值,但它沒有更新UI。

為了證明我的問題,我創造了2個JS小提琴

  1. https://jsfiddle.net/agalo/rjc1Lsbe/4/上的小提琴描述了父子關系規則正常工作的場景。 在這種情況下,Computed Observable屬性最初在對象上定義,不會動態更改。 這非常有效。
  2. https://jsfiddle.net/agalo/uc7yt9tw/4/中的小提琴描述了我當前的規則3和4不起作用的實現。 在這種情況下,單擊按鈕時,將使用計算的Observable覆蓋Observable屬性。 因此,最初不會強制執行父子關系,但是在單擊按鈕時會強制執行關系。

我不是在尋找替代解決方案,但我有興趣了解為什么第二小提琴顯示行為。

 function ViewModel(){ var self = this; var childrenArray = [ {isSelected : ko.observable(true)}, {isSelected : ko.observable(true)}, {isSelected : ko.observable(true)}, {isSelected : ko.observable(true)}]; self.parentChildData = { parentCheckBox: ko.observable(false), children: ko.observableArray([]) }; self.parentChildData.children(childrenArray); self.makeDependent = function(){ self.parentChildData.parentCheckBox = ko.computed({ read: function () { var anyChildUnChecked = ko.utils.arrayFirst(self.parentChildData.children(), function (childCheckBox) { return !childCheckBox.isSelected(); }); var result = anyChildUnChecked == null; return result; //return false; }, write: function (value) { ko.utils.arrayForEach(self.parentChildData.children(), function (childCheckBox) { childCheckBox.isSelected(value); }); } })}; return self; } ko.applyBindings(new ViewModel()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js"></script> <p> Describes my current implementation for which Rule 3 and 4 are not working. In this case, the Observable property is overridden with the computed Observable on the click of the button. So, initially the parent child relationship is not enforced, but on click of button the relationship is enforced. </p> <p> After clicking the button, the first 2 Rules (Rule 1 and 2) works but last 2 Rule (Rule 3 and 4) stops working. I can see in the debugger that the return value is correctly returned but it doesn't Update the UI. </p> <div id="parent"> parent <input type="checkbox" data-bind="checked:parentChildData.parentCheckBox"/> <br/> <div id="child"> Child <!-- ko foreach: parentChildData.children --> <input type="checkbox" data-bind="checked:isSelected"/> <!-- /ko --> </div> <br/> <input type="button" value="Make dependent" data-bind="click:makeDependent"> </div> 

我想問題是在初始化設置時發生的事件序列。 考慮實施中的以下流程 -

  • parentCheckBox首先被定義為self.parentChildData上的一個observable屬性。
  • self.parentChildData.children數組使用子項初始化。
  • parentCheckBox現在更改為computed observable

我在這里看到的問題是,在parentCheckBox被要求對self.parentChildData.childrenself.parentChildData.children所做的更改作出反應self.parentChildData.children ,這個children數組已經初始化,因此沒有創建依賴關系,這就是為什么你沒有得到這種行為你期待。

因此,我更改了代碼的流程並在parentCheckBox被賦予了computedObservable角色之后初始化了self.parentChildData.children (雖然它不會改變最初定義的方式)。

self.parentChildData.parentCheckBox = ko.computed({

read: function() {
  var anyChildUnChecked = ko.utils.arrayFirst(self.parentChildData.children(), function(childCheckBox) {
    return !childCheckBox.isSelected();
  });
  var result = anyChildUnChecked == null;
  return result;

  //return false;
},

write: function(value) {
  ko.utils.arrayForEach(self.parentChildData.children(), function(childCheckBox) {
    childCheckBox.isSelected(value);
  });
}
});

self.parentChildData.children(childrenArray); //values are pushed here

此外,這消除了對self.makeDependent函數的需要,雖然我也很奇怪,當self.parentChildData.children在創建computed之前已經具有值時,該函數如何能夠使其工作: - )

更新了小提琴

暫無
暫無

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

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