2013-01-10 57 views
42

我已經實現了淘汰賽foreach綁定,在同一頁面中有多個模板,其中一個示例在此處給出,我感興趣的是在找出塊的完成時間渲染,我試過afterRenderafterAdd,但我想它運行每個元素,而不是整個循環完成後。成功回調後knockout.js完成渲染所有元素

<ul data-bind="foreach: {data: Contacts, afterAdd: myPostProcessingLogic}"> 
    <li> 
    <div class="list_container gray_bg mrgT3px"> 
     <div class="list_contact_icon"></div> 
     <div class="contact_name"><span data-bind="text: first_name"></span> <span data-bind="text: last_name"></span></div> 
     <div class="contact_number"><span data-bind="text: value"></span></div> 
     <div class="callsms_container"> 
     <a href="#notification-box" class="notifcation-window"> 
      <div class="hover_btn tooltip_call"> 
      <div class="hover_call_icon"></div> 
      <span>Call</span></div> 
     </a> 
     <a class="sendsms" href="#sendsms" rel="#sendsms"> 
      <div class="hover_btn tooltip_sms"> 
      <div class="hover_sms_icon"></div> 
      <span>SMS</span></div> 
     </a> 
     <a href="#"> 
      <div class="hover_more_btn"></div> 
     </a> 
     </div> 
     <!-- close callsms container --> 
     <div id="notification-box" class="notification-popup"> 
     <a href="#" class="close"><img class="btn_close" src="images/box_cross.png" /></a> <img class="centeralign" src="images/notification_call.png" /> <span>Calling... +44 7401 287366</span> </div> 
     <!-- close notification box --> 
     <!-- close list gray bg --> 
     <div class="tooltip_description" style="display:none" id="disp"> asdsadaasdsad </div> 
    </div> 
    </li> 
</ul> 

我有興趣找出循環完成渲染時的成功回調。

這裏是我的afterAdd函數,它基本上附加了一些jQuery事件,沒什麼。

myPostProcessingLogic = function(elements) { 
    $(function(){ 
     $(".list_container_callog").hover(function(){ 
      $(".callsms_container", this).stop().animate({left:"0px"},{queue:false,duration:800}); 
     }, function() { 
      $(".callsms_container", this).stop().animate({left:"-98%"},{queue:false,duration:800}); 
     }); 
    }); 
} 

在此先感謝,並告訴我有一個成功回調:)

回答

62

你有afterRender回調knockout.js

foreach: { data: myItems, afterRender: renderedHandler } 

Here's documentation.

內部處理程序檢查是否渲染集合的長度等於項目集合的長度。如果不是不執行您打算使用的完整呈現邏輯。

renderedHandler: function (elements, data) { 
    if ($('#containerId').children().length === this.myItems().length) { 
     // Only now execute handler 
    } 
} 
+2

我已經使用過。問題在於它在每個元素呈現後都會回調,而我有興趣瞭解所有元素何時完成呈現 – rohitarora

+0

@ user1487459我更新了特定案例的答案。 –

+0

是的,它是相同的我有一個數組的10個項目和它的渲染10次。我得到的問題是每個渲染後執行與每個元素,我只是希望它在所有元素顯示後執行的JS。 – rohitarora

1

上面的解決方案很好。此外,如果您需要使用foreach「作爲」選項,你可以做到這一點像這樣:

data-bind="foreach: { data: myItems, afterRender: renderedHandlet, as: 'myItem'}"> 
9

嘗試包裹ul

<div data-bind='template: {afterRender: myPostProcessingLogic }'> 

它只會在模板內工作的第一次一切被渲染。但是你只會接到myPostProcessingLogic的一個調用。這裏有一個fiddle

<div data-bind='template: {afterRender: myPostProcessingLogic }'> 
    <ul data-bind="foreach: Contacts"> 
    <li> 
     <div class="list_container gray_bg mrgT3px"> 
     <div class="list_contact_icon"></div> 
     <div class="contact_name"><span data-bind="text: first_name"></span> <span data-bind="text: last_name"></span></div> 
     <div class="contact_number"><span data-bind="text: value"></span></div> 
     <div class="callsms_container"> 
      <a href="#notification-box" class="notifcation-window"> 
      <div class="hover_btn tooltip_call"> 
       <div class="hover_call_icon"></div> 
       <span>Call</span></div> 
      </a> 
      <a class="sendsms" href="#sendsms" rel="#sendsms"> 
      <div class="hover_btn tooltip_sms"> 
       <div class="hover_sms_icon"></div> 
       <span>SMS</span></div> 
      </a> 
      <a href="#"> 
      <div class="hover_more_btn"></div> 
      </a> 
     </div> 
     <!-- close callsms container --> 
     <div id="notification-box" class="notification-popup"> 
      <a href="#" class="close"><img class="btn_close" src="images/box_cross.png" /></a> <img class="centeralign" src="images/notification_call.png" /> <span>Calling... +44 7401 287366</span> </div> 
     <!-- close notification box --> 
     <!-- close list gray bg --> 
     <div class="tooltip_description" style="display:none" id="disp"> asdsadaasdsad </div> 
     </div> 
    </li> 
    </ul> 
</div> 
+0

感謝您提供非常好的和乾淨的解決方案。 –

4

採用淘汰賽的容器較少方法喜歡這個只是包裝在foreach到另一個foreach循環:

<!-- ko foreach:{data: Contacts, afterRender: myPostProcessingLogic }--> 
<ul data-bind="foreach: $data}"> 
    <li> 
    <div class="list_container gray_bg mrgT3px"> 
     <div class="list_contact_icon"></div> 
     <div class="contact_name"><span data-bind="text: first_name"></span> <span data-bind="text: last_name"></span></div> 
     <div class="contact_number"><span data-bind="text: value"></span></div> 
     <div class="callsms_container"> 
     <a href="#notification-box" class="notifcation-window"> 
      <div class="hover_btn tooltip_call"> 
      <div class="hover_call_icon"></div> 
      <span>Call</span></div> 
     </a> 
     <a class="sendsms" href="#sendsms" rel="#sendsms"> 
      <div class="hover_btn tooltip_sms"> 
      <div class="hover_sms_icon"></div> 
      <span>SMS</span></div> 
     </a> 
     <a href="#"> 
      <div class="hover_more_btn"></div> 
     </a> 
     </div> 
     <!-- close callsms container --> 
     <div id="notification-box" class="notification-popup"> 
     <a href="#" class="close"><img class="btn_close" src="images/box_cross.png" /></a> <img class="centeralign" src="images/notification_call.png" /> <span>Calling... +44 7401 287366</span> </div> 
     <!-- close notification box --> 
     <!-- close list gray bg --> 
     <div class="tooltip_description" style="display:none" id="disp"> asdsadaasdsad </div> 
    </div> 
    </li> 
</ul> 
<!-- /ko --> 
0

我最近剛做與淘汰賽他們拉入請求添加兩個事件在綁定中定義,解包,然後在呈現項目之前和所有項目渲染之前調用正確的點。我沒有收到任何回覆,但這確實是你想要做的,但你不必寫hacky的代碼來讓它工作。我很驚訝沒有人提出過此要求。我用這些回調函數添加到源代碼中,以銷燬和重新初始化一個敲除綁定的jquery數據表。這是最簡單的解決方案。我在網上看到很多嘗試,嘗試做不同,但這是最簡單的解決方案。

拉要求: - 上面>pr 1856

ko.bindingHandlers.DataTablesForEach = { 

    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
    var nodes = Array.prototype.slice.call(element.childNodes, 0); 
    ko.utils.arrayForEach(nodes, function(node) { 
     if (node && node.nodeType !== 1) { 
     node.parentNode.removeChild(node); 
     } 
    }); 
    return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 

    var value = ko.unwrap(valueAccessor()), 
     key = "DataTablesForEach_Initialized"; 

    var newValue = function() { 
     return { 
     data: value.data || value, 
     beforeRenderAll: function(el, index, data) { 

      if (ko.utils.domData.get(element, key)) { 

      $(element).closest('table').DataTable().destroy(); 
      } 
     }, 
     afterRenderAll: function(el, index, data) { 
      $(element).closest('table').DataTable(value.options); 
     } 
     }; 
    }; 

    ko.bindingHandlers.foreach.update(element, newValue, allBindingsAccessor, viewModel, bindingContext); 

    //if we have not previously marked this as initialized and there is currently items in the array, then cache on the element that it has been initialized 
    if (!ko.utils.domData.get(element, key) && (value.data || value.length)) { 
     ko.utils.domData.set(element, key, true); 
    } 

    return { 
     controlsDescendantBindings: true 
    }; 
    } 
}; 

Knockout Datatables JSFiddle

1

查施奈德的回答是最好的。 我不得不使用無容器控制作爲在foreach是tbody元素上:

<!-- ko template: {afterRender: SetupCheckboxes } --> 
<tbody data-bind="foreach: selectedItems" id="gridBody"> 
    <tr> 
    <td> 
     <input type="checkbox" /> 
    </td> 
    </tr> 
</tbody> 
<!-- /ko --> 
0

嘗試在knockout.js afterRenderAll回調:

的foreach:{數據:myItems,afterRenderAll:myPostProcessingLogic}