knockout.js - 延迟加载模板

Gre*_*eg 15 knockout.js

所以我来自一个模板工作流,它涉及创建一个数据对象(类似于敲除中的视图模型),将其传递给模板引擎(在我们的例子中为jstemplate),使用该数据对象渲染模板,并将其附加到dom.

如何通过淘汰赛实现类似的工作流程?"if"控制流程是我正在寻找的吗?或者将我的模板粘贴在没有数据绑定属性的脚本标记中,并在以后动态添加它们并像ko.applyBindings(viewModel,node)一样处理模板?

我很好奇其他人懒得加载模板使用淘汰赛.

此外,额外的功劳,如果你能告诉我为什么下面的js小提琴不能像我期望的那样工作.我正在尝试学习if控制流绑定,但这不起作用.

http://jsfiddle.net/JJgJ7/1/

RP *_*yer 30

有几个方向你可以这样做:

您可以将不同的视图模型应用于不同的元素,如您所提到的:

var viewModelOne = { ...  };
var viewModelTwo = { ...  };
ko.applyBindings(viewModelOne, containerElementOne);
ko.applyBindings(viewModelOne, containerElementOne);
Run Code Online (Sandbox Code Playgroud)

您甚至可以动态地将绑定及其数据应用于以下元素:

var viewModelOne = { ... };
ko.applyBindingsToNode(containerElement, { template: { name: 'itemTemplate', foreach: items }, viewModelOne);
Run Code Online (Sandbox Code Playgroud)

就像这个样本:http://jsfiddle.net/rniemeyer/gYk6f/

你也可以这样做:

var mainViewModel = {
   sideBarModel = ko.observable(),
   contentModel = ko.observable()
};
Run Code Online (Sandbox Code Playgroud)

然后,绑定它像:

<div data-bind="with: contentModel"></div>
<div data-bind="with: sideBarModel"></div>
Run Code Online (Sandbox Code Playgroud)

它们甚至可以嵌套为:

<div data-bind="with: contentModel">
   ...
   <div data-bind="with: $root.sideBarModel"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

由于模型是可观察的,因此它们最初可以是空的并且可以按需填充.

您当然可以在这些情况下使用命名模板,例如:

<div data-bind="template: { name: "contentTmpl", data: contentModel }"></div>
<div data-bind="template: { name: "sideBarTmpl", data: sideBarModel }"></div>
Run Code Online (Sandbox Code Playgroud)

对于Extra Credit问题:

p标签不能包含其他块级元素(如您的div).浏览器将其移出p标签.div用a 替换你的span行为就像你期望的那样(或替换pdiv).


Loï*_*oix 13

我知道答案仍然很老,我猜你有兴趣看看这个.这是我的模式.有人可能会说我在滥用knockoutjs的概念,但在这里......它有效!

首先,您需要添加一个空模板,这需要敲除至少加载一个模板.如果你提供一些无效的东西,knockoutjs将遗憾地无法工作并中止它在做什么......

假设你有这个.

<script type="text/html" id="template-emtpy">

</script>
Run Code Online (Sandbox Code Playgroud)

酷现在让我们来看看模板是如何在淘汰赛中发挥作用的,淘汰模板实际上只是一个绑定所以它在运行时被检查,并且在工作之前你可以做的所有花哨的事情.这意味着你可以拥有这样的东西.

<div data-bind="template: { name: activeTemplate, data: contentModel }"></div>
Run Code Online (Sandbox Code Playgroud)

其中activeTemplate可以是一个可观察的对象!哦,所以observables在那里工作......当可观察对象发生变化时,模板会被通知,并且会使用正确的模板进行重新渲染.

既然您已经了解我们实际上可以设置模板并在将来进行更改,您就会明白,在我们的模板加载之前,我们将发送敲出空模板.不会有任何绑定错误,因为没有任何东西可以绑定!

现在让我们来看看吧!

<div data-bind="template: { name: getTemplate('reports'), data: contentModel }"></div>
Run Code Online (Sandbox Code Playgroud)

其中getTemplates定义为:

window.getTemplate = function (name) {
    var baseUrl = "/templates/";

    var loaded = ko.observable(false);

    var template = document.getElementById('template-' + name);

    if (template) {
        loaded(true);
    } else {
        jQuery.get(baseUrl + name + '.html', function (data) {
            var scriptTag = $('<script type="text/html" id="template-' + name + '"></script>');
            scriptTag.html(data);
            $('head').append(scriptTag);
            loaded(true);
        });
    }

    return ko.computed(function () {
        if (loaded()) {
            return 'template-' + name;
        } else {
            return "template-empty";
        }
    })();
};
Run Code Online (Sandbox Code Playgroud)

总结一下,我们正在创建一个可观察的加载默认值false.如果我们找到模板,我们将值更改为true.如果没有,我们将尝试使用jQuery加载它(无论你喜欢加载它......你绝对可以放置文本区域并从那里加载模板.一切皆有可能......).

我们返回一个取决于loadedobservable 的计算值.当加载变为true时,它将返回加载的模板的id.由于某些原因,knockoutjs要求文本在脚本html标记内.这就是我用html更新脚本标签的原因.

就是这样了.此外,我可能是错的,我不知道如何敲除处理模板,但它可以切换加载打开和关闭重新加载模板...这意味着你可以有动态加载和可编辑的模板awesomne​​ss! !

还要注意我在返回之前执行计算值.并注意到该功能是全球性的......要解决这个问题!创建自己的绑定来制作类似的东西:

<div data-bind="lazy_template: { name: "reports", data: contentModel }"></div>
Run Code Online (Sandbox Code Playgroud)

然后你很高兴去.您所要做的就是将加载逻辑放在自定义绑定中.

我将在github上创建一个项目,一切正常,我希望它会有所帮助.我稍后会用网址更新.

可能不稳定,因为我在半小时内砍掉它但它对我有用.我可能不得不在某一天写一些测试,但无论如何.玩得开心! https://github.com/llacroix/knockout-lazy-template