Knockout.js - 如何在视图之间切换

时间:2014-01-13 05:10:13

标签: javascript mvvm knockout.js

好吧,新手Knockout问这里。

在此示例中:http://learn.knockoutjs.com/WebmailExampleStandalone.html#Inbox

邮件详细信息视图如何替换文件夹列表视图?

也就是说,什么功能会导致div被切换?在检查dom时,我看到发生的事情是div在未显示时实际呈现为空。

有人可以开导我吗?我知道这是相当基本的,但它是我需要点击的最后一块,以便我理解。

只需100%清除:当您单击文件夹列表中的某一行时,是什么原因导致文件夹视图被清空并显示邮件详细信息?它是with绑定吗? (这似乎不对。)

2 个答案:

答案 0 :(得分:1)

您使用with绑定走在正确的轨道上:在此示例中,使用此feature of the binding上的with绑定中继更改了视图:

  

with绑定将动态添加或删除后代元素,具体取决于相关值是否为null/undefined

因此,在viewmodel代码中,您将看到如下内容:

this.get('#:folder', function () {
    self.chosenFolderId(this.params.folder);
    self.chosenMailData(null);
    $.get("/mail", { folder: this.params.folder }, self.chosenFolderData);
});

this.get('#:folder/:mailId', function () {
    self.chosenFolderId(this.params.folder);
    self.chosenFolderData(null);
    $.get("/mail", { mailId: this.params.mailId }, self.chosenMailData);
});

因此,“链接”视图的函数会在填充另一个属性时将其中一个属性清零,从而切换定义为的视图:

<!-- Chosen mail -->
    <div class="viewMail" data-bind="with: chosenMailData">
    ...
    <div/>

<!-- Mails grid -->
    <table class="mails" data-bind="with: chosenFolderData">
    </table>

这不是最好的解决方案,但不要忘记Knockout是一个Databind / MVVM库,而不是一个完整的SPA框架,因此它没有布局和更高级别视图组合的概念。

然而,使用template binding

可以更好
<div id="mainView" data-bind="{template: {name: templateName, data: activeView}}">
</div>

将视图转换为模板:

<script type="text/html" id="ChosenMail">
    <div class="viewMail">
    ...
    <div/>
</script>

<script type="text/html" id="MailsGrid">
    <table class="mails">
     ...
    </table>
</script>

在路由中只设置activeView属性并为其查找相应的模板名称:

this.get('#:folder', function () {
    $.get("/mail", { folder: this.params.folder }, function(data) {
       self.activeView(data);
       self.templateName('ChosenMail');
    });;
});

this.get('#:folder/:mailId', function () {
    $.get("/mail", { mailId: this.params.mailId }, function(data) {
         self.activeView(data);
         self.templateName('MailsGrid');
    });
});

但是因为这是一个非常多的手动和容易出错的工作,我会使用类似Durandal.js的东西,这是一个真正的SPA框架,它是为这种场景而设计的。

答案 1 :(得分:1)

这只是一个轻量级SPA场景的演示,with绑定只是一个内联模板绑定。对于动态SPA来说不是很有用。像Nemesv建议使用模板绑定。

模板绑​​定的问题在于它的使用非常冗长,我已经在我的Binding约定库中解决了这个问题(许多功能之一)

而不是做

<div id="mainView" data-bind="{template: {name: templateName, data: activeView}}">
</div>

你做

<div id="mainView" data-name="activeView">
</div>

我的图书馆将完成剩下的工作,在这里查看模板上的维基

https://github.com/AndersMalmgren/Knockout.BindingConventions/wiki/Template-convention

还有点小提琴 http://jsfiddle.net/xJL7u/11/