使用KnockoutJs映射插件进行递归模板化 [英] Recursive templating with the KnockoutJs mapping plugin
问题描述
我正在尝试使用 ko.mapping $ b在树上进行递归模板化$ b插件 ,但我不能让它呈现,除非我为每个级别定义单独的
模板。
I am trying to do recursive templating on a tree using the ko.mapping plugin, but I can't get to have it rendered, unless I define separate templates for each level.
在下面的例子中,我想为 mvvmTreeViewSubGroups 重用 mvvmTreeViewGroupTemplate
,但是这是没有呈现的,是
这是一个bug还是没有实现的功能?
In the following case, I want to reuse the mvvmTreeViewGroupTemplate for mvvmTreeViewSubGroups as well, but this is not being rendered, is this a bug or not implemented feature?
<div id="treeViewArea">
<ul data-bind='template: {
name: "mvvmTreeViewGroupTemplate",
foreach: MvvmTreeItemGroups,
beforeRemove: function(elem) { $(elem).slideUp() },
afterAdd: function(elem) { $(elem).hide().slideDown() }
}'>
</ul>
</div>
<script type="text/x-jquery-tmpl" id="mvvmTreeViewGroupTemplate"> <li>
<span data-bind="text: Title" class="mvvmTreeItemStyle"/></br/> <ul data-bind='template: {
name: "mvvmTreeViewItemTemplate",
foreach: MvvmTreeItems,
beforeRemove: function(elem) { $ (elem).slideUp() },
afterAdd: function(elem) { $ (elem).hide().slideDown() }
}'>
<ul data-bind='template: {
name: "mvvmTreeViewSubGroupTemplate",
foreach: this.MvvmTreeItemSubGroups,
beforeRemove: function(elem) { $ (elem).slideUp() },
afterAdd: function(elem) { $ (elem).hide().slideDown() }
}'>
</ul>
</ul>
</li>
</script>
<script type="text/x-jquery-tmpl" id="mvvmTreeViewSubGroupTemplate"> <li>
<span data-bind="text: Title" class="mvvmTreeItemStyle"/></br/>
<ul data-bind='template: {
name: "mvvmTreeViewItemTemplate",
foreach: MvvmTreeItems,
beforeRemove: function(elem) { $ (elem).slideUp() },
afterAdd: function(elem) { $ (elem).hide().slideDown() }
}'>
</ul>
</li>
</script>
JSON和脚本如下所示,
JSON and script looks like this,
var data = {
MvvmTreeItemGroups: [
{
Id: 1, Title: 'Group 1',
MvvmTreeItemSubGroups: [{
Id: 1, Title: 'Group 11',
MvvmTreeItems: [{ Id: 'i111', Title: 'Item 111' },
{ Id: 'i112', Title: 'Item 112'}]
},
{
Id: 1, Title: 'Group 121',
MvvmTreeItems: [{ Id: 'i121', Title: 'Item
121' }, { Id: 'i122', Title: 'Item 122'}]
}],
MvvmTreeItems: [{ Id: 'i11', Title: 'Item 11' }, { Id:
'i12', Title: 'Item 12'}]
},
{
Id: 2, Title: 'Group 2',
MvvmTreeItemSubGroups: [{
Id: 1, Title: 'Group 211',
MvvmTreeItems: [{ Id: 'i211', Title: 'Item
211' }, { Id: 'i212', Title: 'Item 212'}]
},
{
Id: 1, Title: 'Group 121',
MvvmTreeItems: [{ Id: 'i121', Title: 'Item
121' }, { Id: 'i122', Title: 'Item 122'}]
}],
MvvmTreeItems: [{ Id: 'i21', Title: 'Item 21' },
{ Id: 'i22', Title: 'Item 22'}]
}]
};
var viewModel = ko.mapping.fromJS(data);
console.log(viewModel);
ko.applyBindings(viewModel, treeViewArea);
推荐答案
我在此谷歌主题。这不是一个递归模板问题,因为如果没有该名称的数组,模板就不知道如何渲染。
I got an answer to my question in this google thread. It's not exactly a 'recursive templating' issue, it's because the template doesn't know how to render if there is no array by that name.
有两种方法可以解决问题:
There are two ways to fix the issue:
-
检查MvvmTreeItemGroups数组
是否实际存在,然后再渲染
模板,
Check if MvvmTreeItemGroups array actually exists before rendering the template like so,
{{if $data.MvvmTreeItemGroups }}
<ul data-bind='template: {
name: "mvvmTreeViewGroupTemplate",
foreach: MvvmTreeItemGroups }'>
</ul>
{{/if}}
使用in关键字检查
MvvmTreeItemGroups确实存在
Use the in keyword to check MvvmTreeItemGroups really exists
{if 'MvvmTreeItemGroups' in $data}}
<ul data-bind='template: {
name: "mvvmTreeViewGroupTemplate",
foreach: MvvmTreeItemGroups
}'>
</ul>
{{/if}}
完整的小提琴是在 http://jsfiddle.net/mikekidder/Xs7sy/
这篇关于使用KnockoutJs映射插件进行递归模板化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!