2012-07-31 86 views
10

我試圖指定一個入口效應,使用knockoutjs foreach綁定插入的元素。很簡單的設置:knockoutjs afterRender函數在foreach綁定

myViewModel.myObservableArray.push({enter:function() { ... }); 

,並在標記:

foreach:{data:myObservableArray, afterRender:enter} 

似乎像它應該工作,對吧?但它沒有找到該項目的輸入功能。什麼我發現做的工作是:

myViewModel.enter = function(something, item) { item.enter(); }; 

foreach:{data:myObservableArray, afterRender:$root.enter} 

增加一個輸入功能到根視圖模型,並結合afterRender至$ root.enter。回車然後傳遞該項目作爲其第二個參數,所以可以反過來調用該項目的輸入功能,但感覺像一個黑客。

任何人都可以解釋這裏發生了什麼?

謝謝。

編輯:

爲了澄清我已經創建了一個fiddle

這樣做很簡單,在animated transitions example中有更深入的介紹。它在根視圖模型中爲每個使用foreach綁定插入的dom元素運行一個函數。

所以問題是:如果我想項目特定的afterRender,afterAdd或beforeRemove函數?我可以看到這很有用。特別是如果使用模板綁定動態選擇模板(note 4)。有沒有一種乾淨的方式來做到這一點?現在我在視圖模型的根目錄中有一個enter函數,它簡單地調用了項目上的enter函數,但就像我上面所說的那樣,這感覺就像一個黑客。

回答

6

不,這是it was designed的方式。

Documenation

注3:使用「AfterRender階段」,「afterAdd」和「beforeRemove」

有時你可能想上產生的DOM元素自定義運行後處理邏輯通過你的模板。例如,如果您使用的是JavaScript小部件庫(如jQuery UI),則可能需要攔截模板的輸出,以便可以在其上運行jQuery UI命令以將某些呈現的元素轉換爲日期選擇器,滑塊或還要別的嗎。

通常,對DOM元素執行此類後處理的最佳方法是編寫custom binding,但如果您真的只想訪問模板發出的原始DOM元素,則可以使用afterRender。

傳遞一個函數引用(函數文字,或者在您的視圖模型上給出函數的名稱),Knockout將在渲染或重新渲染模板後立即調用它。

(重點煤礦)


,因爲它說,自定義綁定是另一種方式來做到這一點,也可以更好地取決於enter()函數所做的事情。

+1

複製和粘貼文檔並回答問題並不總是一回事。我已經閱讀過文檔。雖然我知道這個論壇並不總是這樣,所以我已經刪除了downvote。這只是沮喪的說話... – nicholas 2012-08-01 22:36:06

+0

@nicholas對不起,它讓你沮喪,我沒有試圖刷你的問題。我試圖做的不僅僅是粘貼文檔,但超越這個解釋非常簡單。你似乎在問爲什麼這樣做,而答案是:因爲它是爲了這個目的而設計的。 – Tyrsius 2012-08-01 22:58:53

+0

是的,在我思考之前,我急於打下按鈕。當然,你是對的。我編輯的問題更清楚。如果我想要做的事(有一個自定義的,特定於項目的,afterAdd函數)不是默認情況下敲除的,那麼問題就變成:我如何讓它做我想做的事?有沒有我沒有看到的技巧?或者是我可以使用的一段代碼?如果有人已經爲我完成了這項工作,我真的不想浪費一天的時間來重建這個foreach綁定... – nicholas 2012-08-02 17:29:32

5

下劃線去抖(_.debounce)在這種情況下是一個很好的解決方案。如果一個AfterRender沒有在過去的100 milisecond解僱

模板

data-bind=" template: {foreach:myObservableArray, afterRender: runWhenAllRenderDone } 

防抖動功能將被執行。

var runWhenAllRenderDone = _.debounce(myFunction, 100); 

function myFunction(){ 
    //do some task but do it for once only 
} 

不是很棒嗎?

+0

這應該是Underscore debounce,而不是Backbone。 – LocalPCGuy 2013-02-05 15:59:50

+0

+1在我的情況下,我不能使用'afterRender'來確保knockout的引擎已經完成了呈現html,因爲我封裝了在observableArray中更改項目的函數的邏輯;代碼不能從html訪問。我知道這並不優雅,但在調用將css添加到新元素節點的另一個函數之前,我還使用了x毫秒的超時時間。實際上,我只設置了1毫秒的超時時間,刷新頁面幾十次後,我沒有看到任何情況,當我的html沒有正確刷新。謝謝。 – Samuel 2014-02-08 15:51:52