2014-09-04 106 views
2

在一個需要生成器的函數中,可能是一個普通的JS Array或一個ko.observableArray,如何以最小的開銷使用observableArrayKnockout:鏈接可觀察數組

這就是目前的代碼看起來像:

function (itemGenerator) { // returns observableArray or JS array 
    var allItems = ko.observable(); 

    // triggered after user interaction 
    var itemsFromGenerator = itemGenerator(); 
    if (ko.isObservable(itemsFromGenerator)) { 
    allItems(itemsFromGenerator()); 

    itemsFromGenerator.subscribe(newValue => { 
     allItems(newValue) 
    }); 
    } else { 
    allItems(children); 
    } 
} 

有什麼辦法與observableArray如果itemsFromGeneratorobservableArray更換allItems?這樣我就不必訂閱「手動」進一步的更改,並且必須拷貝數據。

(這是在一個TreeView的實現,在這裏我只想要生成的項目陣列當一個節點擴展使用。)

回答

1

只要有allItems包含觀察到的陣列,那麼你有外面觀察的跟蹤時可觀察數組被替換。不需要訂閱。

function (itemGenerator) { // returns observableArray or JS array 
    var allItems = ko.observable(); 

    // triggered after user interaction 
    var itemsFromGenerator = itemGenerator(); 
    if (ko.isObservable(itemsFromGenerator)) { 
    allItems(itemsFromGenerator); 
    } else { 
    allItems(ko.observableArray(itemsFromGenerator)); 
    } 
} 

此答案基於您提供的信息。我仍然不知道爲什麼你需要保持對itemsFromGenerator的引用,除非它在這個函數之外以某種方式獨立引用。我也不知道什麼時候// triggered after user interaction下的代碼實際上被調用了。最後,我不知道陣列中的這些項目在哪裏/如何使用。

+0

好的,我希望能夠避免嵌套(可觀察內部的observableArray),但它可能不是那麼糟糕。在observableArrays中包裝普通數組的小開銷在這裏也不是問題。這可能是最好的想法,或者更改API合約,以便itemGenerator總是返回一個observableArray。我已經用這些信息更新了這個問題,這是在TreeView實現中使用的。所以當一個新項目匹配一個搜索查詢時,我希望它自動添加到TreeNode的子項目中。 – Timm 2014-09-05 08:41:58

1

如果我這樣做是正確,你可以使用ko.utils.unwrapObservable()(見好explanation):

你應該在情況下,如果您已獲得可觀察到的使用ko.utils.unwrapObservable,你不知道或者不不。

代碼應該是這樣的:

function ViewModel(itemGenerator) { 
    var self = this; 
    this.itemsFromGenerator = ko.observableArray(); 
    this.generate = function() { 
     self.itemsFromGenerator(ko.utils.unwrapObservable(itemGenerator()));          
    }; 
} 

哪裏generate是你的觸發運行項目發生器。請參閱demo。在generator函數中,您可以在普通數組和可觀察數組之間切換。

+0

Ilya:在我的測試中,當itemGenerator函數創建的observableArray被更新時,這不會更新itemsFromGenerator數組。我不需要從視圖模型內部更新數組,我只想獲取更改,如果它是一個observableArray。看到更新的小提琴:http://jsfiddle.net/483abv7g/1/ – Timm 2014-09-05 08:37:46

+0

順便說一句,截至目前有一個「捷徑」ko.unwrap unwrapObservable(ko.utils.unwrapObservable === ko.unwrap // true)。 – Timm 2014-09-05 08:43:27