2016-08-24 68 views
0

我有一個函數在我的viewmodel中循環遍歷一個數組,並看看 有相似ID的項目(我知道這是錯誤的,因爲ID是唯一的,將改變它一些自定義數據屬性,當我解決這個問題),並檢查他們,如果找到。下面是函數:Knockout - ko.computed和ko.observable.subscribe之間的差異

/* 
    Search for similar terms in taxonomy, 
    if found check/uncheck them 
*/ 

self.srcSimilar = function(tid,val){ 
    _.filter(self.topics(), function(topic) { 
    return _.any(topic.children, function(member) { 
     tid === member.tid ? member.isSelected(val) : ''; 
     return _.any(member.children, function(child) { 
     tid === child.tid ? child.isSelected(val) : '';  
     }); 
    }); 
    }); 
} 

因爲現在,該功能被稱爲child.is選擇觀察到,像這樣的.subscribe方法中:

child.isSelected.subscribe(function(val){ 
    self.srcSimilar(child.tid,val); 
}); 

現在我需要改變孩子。 isSelected可觀察到的可觀察值,因爲checked/unchecked狀態取決於插入到selectedItems可觀察數組中的子項。所以我改變了child.isSelected觀察到:

child.isSelected = ko.computed({ 
    read: function(){ 
    }, 
    write: function(val){ 
    self.srcSimilar(child.tid,val); 
    } 
}); 

......但這最終在控制檯中的「太多遞歸」錯誤。 我在這裏錯過了一些東西,不明白爲什麼.subscribe有效並且ko.computed寫入方法在遞歸中被佔用。 感謝您的幫助。

回答

2

傳遞給訂閱的函數僅在child.isSelected CHANGES時調用。這意味着如果self.srcSimilar集合在同一個正在調用self.src的子節點上被選中,那麼由於該值已經設置且該方法不會遞歸,所以更改事件將不會再次觸發。

然而,通過計算,爲寫入定義的方法將被稱爲每個時間child.isSelected被設置。

想象一下,一個數據集,其中A類似於B.

使用計算

  1. A被一些東西,調用計算的寫設定isSelected(真)。
  2. self.srcSimilar與A.tid一起調用。
  3. self.srcSimilar發現B由於A.tid === B.tid。
  4. B由isSelected(true)通過self.srcSimilar設置,它調用B寫入的計算。
  5. self.srcSimilar與B.tid一起調用。
  6. self.srcSimilar發現A.由於B.tid === A.tid
  7. A由self.srcSimilar它調用計算用於寫
  8. 轉到步驟#2
  9. 設定isSelected(真)

快速訂閱

  1. A被一些東西,呼籲通過訂閱功能設置。
  2. self.src與A.tid一起調用
  3. self.src類似地找到B,歸因於A.tid === B.tid。
  4. B被self.srcSimilar設置爲isSelected(true),它調用傳遞給訂閱的函數。
  5. self.src與B一起調用類似。tid
  6. self.srcSimilar發現B由於A.tid === B.tid。
  7. A設置爲isSelected(true),但因爲isSelected已經爲true,所以傳遞給訂閱的函數不會被調用。
+0

謝謝@Timo,真的很清楚,很有幫助。 –

相關問題