Успешный обратный вызов после завершения knockout.js, рендеринг всех элементов
Я реализовал привязку нокаута foreach с несколькими шаблонами на одной странице, здесь приведен один из примеров, мне интересно узнать, когда блок заканчивает рендеринг, я пробовал afterRender
и afterAdd
, но я предполагаю, что он выполняется для каждого элемента, а не после завершения всего цикла.
<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});
});
});
}
Заранее спасибо и скажите, что есть обратный вызов успеха:)
Ответы
Ответ 1
У вас есть обратный вызов afterRender
в knockout.js
:
foreach: { data: myItems, afterRender: renderedHandler }
Здесь документация.
Внутри обработчика проверьте, равна ли длина выделенной коллекции длине коллекции элементов. Если не выполнить полную визуализированную логику, которую вы собираетесь использовать.
renderedHandler: function (elements, data) {
if ($('#containerId').children().length === this.myItems().length) {
// Only now execute handler
}
}
Ответ 2
Попробуйте обернуть ul
с помощью
<div data-bind='template: {afterRender: myPostProcessingLogic }'>
Он будет работать только при первом отображении всего в шаблоне. Но вы получите только один вызов myPostProcessingLogic. Здесь скрипка
<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>
Ответ 3
Просто оберните 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 -->
Ответ 4
Ответ Чак Шнайдера выше, лучший.
Мне пришлось использовать управление без контейнера, поскольку foreach находится на элементе tbody:
<!-- ko template: {afterRender: SetupCheckboxes } -->
<tbody data-bind="foreach: selectedItems" id="gridBody">
<tr>
<td>
<input type="checkbox" />
</td>
</tr>
</tbody>
<!-- /ko -->
Ответ 5
Решение выше отлично работает. Кроме того, если вам нужно использовать опцию "как" foreach, вы можете сделать это так:
data-bind="foreach: { data: myItems, afterRender: renderedHandlet, as: 'myItem'}">
Ответ 6
Я только что недавно сделал запрос на выгрузку с нокаутом для них, чтобы добавить два события для определения в привязке, разворачивании, затем вызвать правильные точки перед рендерингом элементов и после того, как все элементы были отображены. Я ничего не слышал от них, но это делает именно то, что вы хотите сделать, но вам не нужно писать хакерский код, чтобы заставить его работать. Я удивлен, что раньше никто этого не делал. Я использовал эти обратные вызовы, которые я добавил к источнику для уничтожения и повторной инициализации связанного с нокаутом jquery datatable. Это было самое простое решение. Я видел много попыток онлайн, которые пытаются и делают это по-другому, но это самое простое решение.
Запрос Pull: → 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
};
}
};
Нокаут Datatables JSFiddle
Ответ 7
Попробуйте afterRenderAll
обратный вызов в knockout.js:
foreach: {данные: myItems, afterRenderAll: myPostProcessingLogic}
Ответ 8
В версии 3.5 Knockout предоставляет события для уведомления, когда содержимое узла было связано
HTML
<div data-bind="childrenComplete: bindingComplete">...</div>
JavaScript
function bindingComplete(){
...
}
Если вы находитесь в выражении привязки данных в точке в DOM, которая инкапсулирует все настроенное выражение привязки данных, то это равносильно событию завершения привязки для всех узлов
ссылкаhttps://knockoutjs.com/documentation/binding-lifecycle-events.html