Javascript 如何在KO外部模板引擎中使用本机敲除模板
我正在使用KO外部模板引擎将我的单页webapp分解为多个文件,但我正在加载的模板只包含KO标记 尽管对这个主题进行了广泛的研究,但我还是不知道如何将KO绑定可靠地应用于正在加载的模板 关键是:Javascript 如何在KO外部模板引擎中使用本机敲除模板,javascript,jquery,knockout.js,knockout-templating,Javascript,Jquery,Knockout.js,Knockout Templating,我正在使用KO外部模板引擎将我的单页webapp分解为多个文件,但我正在加载的模板只包含KO标记 尽管对这个主题进行了广泛的研究,但我还是不知道如何将KO绑定可靠地应用于正在加载的模板 关键是: 模板定义的DOM元素最初不存在 我的模板绑定是动态的,所以我不知道KO在对整个文档应用绑定时会请求模板 我不想使模板加载同步 pb变得更加棘手,因为infuser可能正在进行一些模板缓存,这导致KO抱怨我应用了两次绑定 这是我的代码,它至少有两个问题: 当我调用applyBindings时,不能保
- 模板定义的DOM元素最初不存在
- 我的模板绑定是动态的,所以我不知道KO在对整个文档应用绑定时会请求模板
- 我不想使模板加载同步
- pb变得更加棘手,因为infuser可能正在进行一些模板缓存,这导致KO抱怨我应用了两次绑定
- 当我调用applyBindings时,不能保证模板已经完成加载
- KO抱怨我在来回导航时试图重新应用绑定
- 在index.html中:
<div data-bind="with: block1">
<input data-bind="value: yourFirstInput" />
<!-- more markeup -->
</div>
<div data-bind="with: block2">
<select data-bind="options: dropDownlist2options"></select>
<!-- more markeup -->
</div>
这样,您可以在整个页面上应用绑定。带绑定的将处理空/未定义对象的检查,并仅在对象实例化时显示块
然后,当您想显示块1
时,可以执行类似操作:
vm.block1({ yourFirstInput: ko.observable('aa')});
实际上,我是通过映射插件实现的,这只是一个例子
(注意设置超时后block1是如何显示的)如果我给了你一个要点,那么你可以这样做
使用get和assign-to-script标记将模板加载到js中的一个基本文件中,如下所示
var script = document.createElement("script");
script.id = "YourTemplateName";
script.type = "text/html";
script.text = result.Value; //template data
document.body.appendChild(script);
并在索引/基本html文件中指定模板
<div id="OtherTemplateDiv" data-bind="template: { name: 'YourTemplateName' }">
</div>
我为KO制作了一个模板引擎
它需要一个启用Owin的web服务器,一旦配置好,它就知道名为FooViewModel
的视图模型应该连接到名为FooView
使用nuget安装(适用于ASP.NET)
它的设计也很容易在水疗中心使用
演示
我想出了一些使用afterRender回调的方法。。。虽然有点凌乱,但我们欢迎改进
由于某种原因,afterRender回调被调用了两次,第二次调用的对象为空,因此需要对hasOwnProperty('nodeType')进行测试
isBound()检查绑定是否已应用于元素-在应用绑定失败后,尝试向元素添加自定义标记CSS(“ko-applicated”)类
不确定是否确实需要复制koElements数组,但如果不这样做,我的循环中就有未定义的元素[I],因此模板加载程序可能会在afterRender运行时异步更新数组
<div id="templateDiv" data-bind="template: { name: currentView(), afterRender: applyTemplateBindings }"></div>
self.applyTemplateBindings = function(koElements) {
var elements = koElements.slice();
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
if (element.hasOwnProperty('nodeType') && ! $(element).hasClass('infuser-loading') &&
! isBound(element)) {
ko.applyBindings(self, element);
}
}
};
var isBound = function(node) {
return !!ko.dataFor(node);
};
self.applyTemplateBindings=函数(元素){
var elements=koElements.slice();
for(var i=0,len=elements.length;i
Hmmm,问题是我可能有50多个外部模板,所以我不想在调用applyBindings()之前加载所有模板。因为所有DOM节点(主文档和所有模板)都是在调用applyBindings之前创建的,所以fiddle可以工作,不是吗?实际上,重要的是在调用相关DOM元素上的applyBindings之前定义块。您可以在之后加载标记,但是您必须对其调用applyBindings(ko.applyBindings(vm,domElement)),我已经解决了这一部分。问题在于在初次调用applyBindings后加载的外部模板(比如在通过应用程序导航15分钟后,用户突然导航到加载新模板的视图)。请尝试类似这样的操作:ko.applyBindings(objectLateLoaded,$(“#DivIdInWhichTemplateAdded”)[0];
var script = document.createElement("script");
script.id = "YourTemplateName";
script.type = "text/html";
script.text = result.Value; //template data
document.body.appendChild(script);
<div id="OtherTemplateDiv" data-bind="template: { name: 'YourTemplateName' }">
</div>
Install-Package Knockout.Bootstrap.TemplateStore.SystemWeb
<div id="templateDiv" data-bind="template: { name: currentView(), afterRender: applyTemplateBindings }"></div>
self.applyTemplateBindings = function(koElements) {
var elements = koElements.slice();
for (var i = 0, len = elements.length; i < len; i++) {
var element = elements[i];
if (element.hasOwnProperty('nodeType') && ! $(element).hasClass('infuser-loading') &&
! isBound(element)) {
ko.applyBindings(self, element);
}
}
};
var isBound = function(node) {
return !!ko.dataFor(node);
};