Как использовать jQuery в шаблоне Knockout.js?
Я пытаюсь настроить таргетинг на элемент, используя jQuery, который встроен в один из моих шаблонов выбивки:
<script type="text/html" id="video-file-template">
<div class="video" data-bind="attr: { 'data-index': $index }">
</div>
</script>
Тем не менее, когда я пытаюсь выбрать $('.video')
используя jQuery, завернутый в функцию готовности документа, я получаю объект с возвращаемой длиной 0:
$(document).ready(function() {
console.log($('.video')); // Returns an object with a length of 0
});
Почему это? Это потому, что элемент не является частью DOM, когда мой скрипт jQuery оценивается? Если это так, как я могу нацелить элемент, когда он загружается в DOM через Knockout.js?
2 ответа
Это правда, что документ уже готов ko.applyBindings
заканчивается, поэтому вы не видите элемент. Тем не менее, вы не должны использовать jQuery для нарушения границы между вашей моделью представления и DOM. В нокауте, способ выполнить то, что вам нужно, с помощью пользовательских привязок.
По сути, вы определяете новую привязку нокаута (например, текст, значение, foreach и т. Д.), И у вас есть доступ к init
функция, которая запускается при первом отображении элемента, и update
функция, которая запускается при обновлении значения, передаваемого в привязку. В вашем случае вам нужно будет только определить init
:
ko.bindingHandlers.customVideo = {
init: function (element) {
console.log(element, $(element)); // notice you can use jquery here
}
};
И тогда вы используете привязку, как это:
<div data-bind="customVideo"></div>
Возможно, лучше добавить класс video и выполнить другую инициализацию прямо в обратном вызове init:
ko.bindingHandlers.customVideo = {
init: function (element) {
$(element).addClass('video');
}
};
Если это поначалу кажется немного странным, помните, что есть очень веская причина для косвенного обращения. Он сохраняет вашу модель представления отдельно от DOM, к которой он относится. Таким образом, вы можете менять DOM более свободно и тестировать модель представления более независимо. Если вы ждали ko.applyBindings
чтобы закончить и вызвать некоторые вещи jQuery после этого, вам будет сложнее протестировать этот код. Обратите внимание, что выбиваемые пользовательские привязки никоим образом не являются "специальными", и вы можете видеть, что встроенные привязки определены точно так же: https://github.com/knockout/knockout/tree/master/src/binding/defaultBindings
Как указывалось в предыдущих комментариях, это происходит потому, что ваш $(document).ready срабатывает до того, как ваши шаблоны выбывания были обработаны.
Всякий раз, когда мне нужно сделать что-то подобное, я склонен иметь функцию 'init' (или любую другую) в моей модели ko view, которую я вызываю после завершения applyBindings;
Так:
var ViewModel = function(){
var self=this;
//blah
self.init = function(){
//jquery targeting template elements
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
vm.init();