好吧,新手Knockout问这里。
在此示例中:http://learn.knockoutjs.com/WebmailExampleStandalone.html#Inbox
邮件详细信息视图如何替换文件夹列表视图?
也就是说,什么功能会导致div被切换?在检查dom时,我看到发生的事情是div在未显示时实际呈现为空。
有人可以开导我吗?我知道这是相当基本的,但它是我需要点击的最后一块,以便我理解。
只需100%清除:当您单击文件夹列表中的某一行时,是什么原因导致文件夹视图被清空并显示邮件详细信息?它是with
绑定吗? (这似乎不对。)
答案 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