KnockoutJS 绑定
KnockoutJS Binding
我有在 ajax 应用程序中创建的视图模型。 ko.applyBindings() 在我渲染第一个 html 时被调用。后来我进行了第二次 ajax 调用以呈现 html 的另一部分并绑定到相同的视图模型。但是,因为当我第一次调用 ko.applyBindings() 时第二个 ajax 中的 html 元素不存在,所以当我检索 html 的第二部分时,数据绑定会不行。
这是一个非常简单的示例,其中第一个复选框已正确绑定。然后 content2 将通过后续的 ajax 调用加载,并且复选框无法绑定
<div id='container'>
<div id="content1"> <span>Opt In</span>
<input data-val-required="field is required." id="cbOptIn" name="OptIn" type="checkbox" data-bind="checked: OptIn"/>
</div>
</div
var ViewModel = function () {
var self = this;
self.OptIn = ko.observable(false);
self.OptIn2 = ko.observable(false);
}
var appVM = new ViewModel();
ko.applyBindings(appVM);
appVM.OptIn(true);
var content2 = document.createElement('div');
content2.id = 'content2';
content2.innerHTML = '<span>Opt In2</span><input data-val-required="field is required." id="cbOptIn2" name="OptIn2" type="checkbox" data-bind="checked: OptIn2"/>';
document.getElementById('container').appendChild(content2);
appVM.OptIn2(true);
我也曾尝试通过创建两个单独的视图模型来解决这个问题,但后来我得到了
"You cannot apply bindings multiple times to the same element."
我假设您的精简版本在功能上与您的实际情况不同,并且您正在使用 jQuery load() 调用来引入片段。如果是这样的话,有您可以使用几个函数来重新应用绑定:ko.dataFor()
、ko.cleanNode()
和 ko.applyBindings()
.
如果您要将片段加载到元素中:
element.load('path/to/fragment.html', function() {
// do stuff
});
并且该元素或其他一些父元素已绑定到视图模型,您可以使用如下函数重新应用绑定:
var reapplyBindings = function(element) {
// grab the viewmodel that has been applied to this element
var viewModel = ko.dataFor(element);
// if the viewmodel exists, clean the node and re-apply the viewmodel
// to the element (and all of it's children)
if(viewModel) {
ko.cleanNode(element);
ko.applyBindings(vm, element);
}
}
现在,要使用这个功能:
element.load('path/to/fragment.html', function() {
reapplyBindings(element);
// do stuff you were doing before
});
这是有效的,因为即使您可能没有明确地将视图模型应用到要加载到的元素上,knockout 仍然可以从 DOM.
的更上方抓取视图模型
这种方法唯一真正需要注意的是 cleanNode
函数;它将删除所有事件处理程序,因此需要重新应用它们(除非您将它们附加到父元素,在这种情况下您很好)。
我有在 ajax 应用程序中创建的视图模型。 ko.applyBindings() 在我渲染第一个 html 时被调用。后来我进行了第二次 ajax 调用以呈现 html 的另一部分并绑定到相同的视图模型。但是,因为当我第一次调用 ko.applyBindings() 时第二个 ajax 中的 html 元素不存在,所以当我检索 html 的第二部分时,数据绑定会不行。
这是一个非常简单的示例,其中第一个复选框已正确绑定。然后 content2 将通过后续的 ajax 调用加载,并且复选框无法绑定
<div id='container'>
<div id="content1"> <span>Opt In</span>
<input data-val-required="field is required." id="cbOptIn" name="OptIn" type="checkbox" data-bind="checked: OptIn"/>
</div>
</div
var ViewModel = function () {
var self = this;
self.OptIn = ko.observable(false);
self.OptIn2 = ko.observable(false);
}
var appVM = new ViewModel();
ko.applyBindings(appVM);
appVM.OptIn(true);
var content2 = document.createElement('div');
content2.id = 'content2';
content2.innerHTML = '<span>Opt In2</span><input data-val-required="field is required." id="cbOptIn2" name="OptIn2" type="checkbox" data-bind="checked: OptIn2"/>';
document.getElementById('container').appendChild(content2);
appVM.OptIn2(true);
我也曾尝试通过创建两个单独的视图模型来解决这个问题,但后来我得到了
"You cannot apply bindings multiple times to the same element."
我假设您的精简版本在功能上与您的实际情况不同,并且您正在使用 jQuery load() 调用来引入片段。如果是这样的话,有您可以使用几个函数来重新应用绑定:ko.dataFor()
、ko.cleanNode()
和 ko.applyBindings()
.
如果您要将片段加载到元素中:
element.load('path/to/fragment.html', function() {
// do stuff
});
并且该元素或其他一些父元素已绑定到视图模型,您可以使用如下函数重新应用绑定:
var reapplyBindings = function(element) {
// grab the viewmodel that has been applied to this element
var viewModel = ko.dataFor(element);
// if the viewmodel exists, clean the node and re-apply the viewmodel
// to the element (and all of it's children)
if(viewModel) {
ko.cleanNode(element);
ko.applyBindings(vm, element);
}
}
现在,要使用这个功能:
element.load('path/to/fragment.html', function() {
reapplyBindings(element);
// do stuff you were doing before
});
这是有效的,因为即使您可能没有明确地将视图模型应用到要加载到的元素上,knockout 仍然可以从 DOM.
的更上方抓取视图模型这种方法唯一真正需要注意的是 cleanNode
函数;它将删除所有事件处理程序,因此需要重新应用它们(除非您将它们附加到父元素,在这种情况下您很好)。