嵌套组件也预先假定嵌套视图模型。
但是,在示例组件中,我没有看到这种依赖性出现(除了对于KO用户来说不太清楚的BackboneJS TODO应用程序)。
您能否详细说明如何进行此类设计,例如:收集:
ItemViewModel
包含属性Name
和IsSelected
CollectionViewModel
具有Items
属性,其中包含ItemViewModel
和SelectedCount
的集合,该集合是通过计算选择的项目数来计算的。 (我知道这可以用KO以更简单的方式完成,但是为了说明。答案 0 :(得分:2)
Viewmodels(VM)只是对象(使用ko.applyBindings()
绑定) - 这意味着您可以任意将VM嵌套到父对象中(@Hasith所说的)。您只需将一个父对象传递回Boilerplate。请注意一些超评论代码:
// Let's assume you have your items nicely formatted in an array
// data source (and technically the objects in this array can be
// considered 'dumb' viewmodels)
var items = [
{Name:'a',isSelected:false},
{Name:'b',isSelected:true}
]
// We can apply some bindings to make 'smarter' viewmodels
// One approach is just to map using rocking KO mapping plugin
var koMapItems = ko.mapping.fromJS( items )
// You could skip the mapping plugin and go for broke
// creating your own VM mappings manually
// (you could do this using the mapping plugin with less work)
var goforbrokeVM = function( item )
{
var _name = ko.observable( item.Name )
var _dance = function() { return _name+' is space monkey' }
return {
Name: _name,
isSelected: ko.observable( item.isSelected ),
spaceMonkey: _dance
}
}
// Don't forget to assign and create your goforbrokeVMs
var epicItemVMs = []
for (var i=0;i<items.length;i++)
epicItemVMs.push( new goforbrokeVM( items[i]) )
// Now the interesting part, lets create a 'child' VM that
// we can embed in another VM. Notice this VM has as a
// property an array of VMs itself.
var childVM = {
elements: epicItemVMs,
// A sub method, because we can
otherMethod: function() { return 'wat' }
}
// And ultimately our 'master' VM with its own properties
// including the nested child VM we setup above (which you'll
// remember contains its own sub VMs)
var ParentVM = {
// And its own property
parentPropA: ko.observable('whatever'),
// Oooow look, a list of alternative ko.mapping VMs
simpleMappedItems: koMapItems,
// And a nested VM with its own nested goforbrokeVMs
nested: childVM
}
// Apply your master viewmodel to the appropriate DOM el.
ko.applyBindings( ParentVM, document.getElementById('items'))
你的HTML:
<div id="items">
<span data-bind="text: parentPropA"></span>
<!-- Step through one set of items in ParentVM -->
<div data-bind="foreach: simpleMappedItems">
<input type="checkbox" data-bind="checked: isSelected">
<span data-bind="text: Name"></span>
</div>
<!-- Or jump into the nested models and go crazy -->
<!-- ko with: nested -->
<div data-bind="foreach:elements">
<div data-bind="text: spaceMonkey"></div>
</div>
<div data-bind="text: otherMethod"></div>
<!-- /ko -->
</div>
通过这种方式,您可以根据需要将单个对象(在本例中为ParentVM
)传递给Boilerplate,并使用尽可能多的嵌套视图模型。
有关淘汰生活的地图插件的信息:http://knockoutjs.com/documentation/plugins-mapping.html
答案 1 :(得分:-1)
'todo'样本是通过采用Addy Osmani的实现完成的。 还有一个knockoutjs的实现here。