淘汰赛 - 重用相同的视图模型

时间:2013-06-06 16:37:39

标签: javascript knockout.js

我们举一个购物车的例子......

每次用户选择项目时,我们都会将其移动到购物车的一行。

/* would normally autoincrement */ 
var num = '1'; 
document.getElementById('cart').innerHTML = oldHTML + 
"<div id='line" + num + "'>
<input type='text' data-bind='value: quantity'>
<input type='text' data-bind='value: price'>
<input type='text' data-bind='value: extendedPrice'>
</div>";`

var lineVM () {
    var self = this;
    self.quantity = ko.observable();
    self.price = ko.observable();
    self.extendedPrice = ko.computed(function () {return self.price() * self.quantity();});
}

ko.applyBindings(new lineVM(), document.getElementById('line' + num));

随着行的添加,我们有line1,line2等......

来自文档:

  

或者,您可以传递第二个参数来定义要搜索数据绑定属性的文档的哪个部分。例如,ko.applyBindings(myViewModel,document.getElementById('someElementId'))。这会将激活限制为具有ID someElementId及其后代的元素,如果您希望拥有多个视图模型并将每个视图模型与页面的不同区域相关联,这将非常有用。

测试显示没有分离...如果我重用视图模型,那么添加另一行“空白”前面的那个。但是,对于不确定数量的行,我需要相同的视图模型。我不想为每个潜在的生产线创建100个视图模型,我不希望我的购物车打破了将有101个项目的客户。

那么,如果我有一个视图模型并希望将其与页面上的多个区域相关联,该怎么办?文档并没有真正说出来。我是以错误的方式做的,我是否正在尝试做Knockout不允许的事情?

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:2)

我认为你应该重新考虑你的整体设计。为什么不这样做呢?

var viewModel = function () {
    var self = this;
    self.items = ko.observableArray();
    self.addItem = function(num, quantity, price) {
        var item = {
            num: num,
            quantity: ko.observable(quantity),
            price: ko.observable(price)
        };
        item.extendedPrice = ko.computed(function() {
            return item.price() * item.quantity();
        }, self);
        self.items.push(item);
    };
};

ko.applyBindings(new viewModel());

HTML:

<div data-bind="foreach: items">
    <div data-bind="attr: { id: 'line' + num }">
        <input type="text" data-bind="value: quantity" />
        <input type="text" data-bind="value: price" />
        <input type="text" data-bind="value: extendedPrice" readonly="readonly" />
    </div>
</div>

原则是将项添加到observableArray以更改视图。你真的不应该动态创建视图模型。

使用此代码,您必须有一些方法来调用self.addItem,这取决于您设计代码的其余部分。

修改,顺便说一下,代码中的var lineVM () {行应为var lineVM = function () {

此外,对不起,如果此代码的某些人无法正常工作,则未经测试,但应该可以帮助您理解。