admin管理员组文章数量:1022443
I'm trying to target an element using jQuery which is embedded in one of my knockout templates:
<script type="text/html" id="video-file-template">
<div class="video" data-bind="attr: { 'data-index': $index }">
</div>
</script>
Yet, when I attempt to select $('.video')
using jQuery, wrapped in a document ready function, I get an object with a length of 0 returned:
$(document).ready(function() {
console.log($('.video')); // Returns an object with a length of 0
});
Why is this? Is it because the element is not part of the DOM when my jQuery script is evaluated? If so, how can I target the element when it is loaded into the DOM via Knockout.js?
I'm trying to target an element using jQuery which is embedded in one of my knockout templates:
<script type="text/html" id="video-file-template">
<div class="video" data-bind="attr: { 'data-index': $index }">
</div>
</script>
Yet, when I attempt to select $('.video')
using jQuery, wrapped in a document ready function, I get an object with a length of 0 returned:
$(document).ready(function() {
console.log($('.video')); // Returns an object with a length of 0
});
Why is this? Is it because the element is not part of the DOM when my jQuery script is evaluated? If so, how can I target the element when it is loaded into the DOM via Knockout.js?
Share Improve this question asked Mar 10, 2015 at 3:49 marked-downmarked-down 10.4k22 gold badges93 silver badges153 bronze badges 4-
Where are you using this template(
#video-file-template
)?? – Madhu Commented Mar 10, 2015 at 4:05 - Template is not evaluated as DOM element. I think you didn't bind your template using knockout before querying the DOM. – Nhân Nguyễn Commented Mar 10, 2015 at 5:30
- Yes, defenitely you're trying to execute you jquery statement before KO bindings are applied. Check the order of script execution. – Rango Commented Mar 10, 2015 at 8:58
-
The next question would of course be why you are trying to get the element using jQuery in a
$(document).ready
callback. I don't know much about your specific scenario, but my guess would be that you'd be a lot better off creating a custom bindingHandler which performs the logic you want. – Robert Westerlund Commented Mar 10, 2015 at 9:34
2 Answers
Reset to default 5It's true that the document is ready before ko.applyBindings
finishes, so that's why you're not seeing the element. However, you should not be using jQuery to violate the boundary between your view model and the DOM like that. In knockout, the way to acplish what you need is with custom bindings.
Basically, you define a new knockout binding (like text, value, foreach, etc) and you have access to an init
function, which fires when the element is first rendered, and an update
function, which fires when the value you pass to the binding is updated. In your case, you would only need to define init
:
ko.bindingHandlers.customVideo = {
init: function (element) {
console.log(element, $(element)); // notice you can use jquery here
}
};
And then you use the binding like this:
<div data-bind="customVideo"></div>
Perhaps it's better to add the "video" class and do other initialization right in the init callback:
ko.bindingHandlers.customVideo = {
init: function (element) {
$(element).addClass('video');
}
};
If this feels a little wonky at first, remember there's a very good reason for the indirection. It keeps your view model separate from the DOM it applies to. So you can change the DOM more freely and you can test the view model more independently. If you waited for ko.applyBindings
to finish and called some jQuery stuff after that, you'd have a harder time testing that code. Notice that knockout custom bindings are not "special" in any way, and you can see that the built in bindings are defined exactly the same: https://github./knockout/knockout/tree/master/src/binding/defaultBindings
As the previous ments have suggested, it's because your $(document).ready fires before your knockout templates have been rendered.
Whenever I need to do this sort of thing I tend to have an 'init' (or whatever) function on my ko view model that I call after applyBindings has pleted;
So:
var ViewModel = function(){
var self=this;
//blah
self.init = function(){
//jquery targeting template elements
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
vm.init();
I'm trying to target an element using jQuery which is embedded in one of my knockout templates:
<script type="text/html" id="video-file-template">
<div class="video" data-bind="attr: { 'data-index': $index }">
</div>
</script>
Yet, when I attempt to select $('.video')
using jQuery, wrapped in a document ready function, I get an object with a length of 0 returned:
$(document).ready(function() {
console.log($('.video')); // Returns an object with a length of 0
});
Why is this? Is it because the element is not part of the DOM when my jQuery script is evaluated? If so, how can I target the element when it is loaded into the DOM via Knockout.js?
I'm trying to target an element using jQuery which is embedded in one of my knockout templates:
<script type="text/html" id="video-file-template">
<div class="video" data-bind="attr: { 'data-index': $index }">
</div>
</script>
Yet, when I attempt to select $('.video')
using jQuery, wrapped in a document ready function, I get an object with a length of 0 returned:
$(document).ready(function() {
console.log($('.video')); // Returns an object with a length of 0
});
Why is this? Is it because the element is not part of the DOM when my jQuery script is evaluated? If so, how can I target the element when it is loaded into the DOM via Knockout.js?
Share Improve this question asked Mar 10, 2015 at 3:49 marked-downmarked-down 10.4k22 gold badges93 silver badges153 bronze badges 4-
Where are you using this template(
#video-file-template
)?? – Madhu Commented Mar 10, 2015 at 4:05 - Template is not evaluated as DOM element. I think you didn't bind your template using knockout before querying the DOM. – Nhân Nguyễn Commented Mar 10, 2015 at 5:30
- Yes, defenitely you're trying to execute you jquery statement before KO bindings are applied. Check the order of script execution. – Rango Commented Mar 10, 2015 at 8:58
-
The next question would of course be why you are trying to get the element using jQuery in a
$(document).ready
callback. I don't know much about your specific scenario, but my guess would be that you'd be a lot better off creating a custom bindingHandler which performs the logic you want. – Robert Westerlund Commented Mar 10, 2015 at 9:34
2 Answers
Reset to default 5It's true that the document is ready before ko.applyBindings
finishes, so that's why you're not seeing the element. However, you should not be using jQuery to violate the boundary between your view model and the DOM like that. In knockout, the way to acplish what you need is with custom bindings.
Basically, you define a new knockout binding (like text, value, foreach, etc) and you have access to an init
function, which fires when the element is first rendered, and an update
function, which fires when the value you pass to the binding is updated. In your case, you would only need to define init
:
ko.bindingHandlers.customVideo = {
init: function (element) {
console.log(element, $(element)); // notice you can use jquery here
}
};
And then you use the binding like this:
<div data-bind="customVideo"></div>
Perhaps it's better to add the "video" class and do other initialization right in the init callback:
ko.bindingHandlers.customVideo = {
init: function (element) {
$(element).addClass('video');
}
};
If this feels a little wonky at first, remember there's a very good reason for the indirection. It keeps your view model separate from the DOM it applies to. So you can change the DOM more freely and you can test the view model more independently. If you waited for ko.applyBindings
to finish and called some jQuery stuff after that, you'd have a harder time testing that code. Notice that knockout custom bindings are not "special" in any way, and you can see that the built in bindings are defined exactly the same: https://github./knockout/knockout/tree/master/src/binding/defaultBindings
As the previous ments have suggested, it's because your $(document).ready fires before your knockout templates have been rendered.
Whenever I need to do this sort of thing I tend to have an 'init' (or whatever) function on my ko view model that I call after applyBindings has pleted;
So:
var ViewModel = function(){
var self=this;
//blah
self.init = function(){
//jquery targeting template elements
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
vm.init();
本文标签: javascriptHow to use jQuery in a Knockoutjs TemplateStack Overflow
版权声明:本文标题:javascript - How to use jQuery in a Knockout.js Template? - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745573271a2156866.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论