【问题标题】:knockoutjs: computed observables in cascaded arrays (complex viewmodel) and the this-pointerknockoutjs:级联数组(复杂视图模型)和 this 指针中的计算 observables
【发布时间】:2014-08-23 04:37:22
【问题描述】:

编辑: 按照建议,我重构了我的视图模型:
- 使用构造函数
- 使用子“事物”

这里是小提琴:http://jsfiddle.net/drchef/hSMkc/1/

现在,计算出来了 ;) thx

但还有一个问题: 如果我更改食物值,这些值不会回到模型中。 元数据正在工作,但食物价值没有。 (所以总数不会更新)

P.S.:对不起,我是新来的...我应该开始一个新问题吗?

================================================ =============

首先,我发布我的视图模型;)

var vm = function() {

var self = this;    

this.activeRow = ko.observable(0);
this.user = 'hungry guy';

this.foods = ['pizza', 'burger', 'chilli'];
this.meetings = [
    {year: 2014, types: [{type: "until now", hidden: false}, {type: "forecast", hidden: false}]},
    {year: 2015, types: [{type: "forecast", hidden: false}]}
];

this.lines = ko.observableArray([
    {   id: 1,
        meta: ko.observable(
            {   shop: ko.observable('foodstore'),
                tel: ko.observable('123 456'),
                url: ko.observable('foodstore24.com')
            }),
        meetingValues: ko.observableArray([
            {   productValues: ko.observableArray([
                    {productValue: ko.observable(1)},
                    {productValue: ko.observable(0)},
                    {productValue: ko.observable(1)}]),
                total: ko.computed(function() {
                    //console.log(this.lines) -> expected: array output -> actual: undefined
                    //console.log(this.lines()) -> expected: array output -> actual: error, this.lines() ist not a function
                    //console.log(this) -> expected: this == self -> actual: this == self
                    return 0;
                }, this)
            },
            {   productValues: ko.observableArray([
                    {productValue: ko.observable(3)},
                    {productValue: ko.observable(2)},
                    {productValue: ko.observable(5)}]),
                total: ko.computed(function() {
                    return 0;
                })
            },
            {   productValues: ko.observableArray([
                    {productValue: ko.observable(2)},
                    {productValue: ko.observable(2)},
                    {productValue: ko.observable(3)}]),
                total: ko.computed(function() {
                    return 0;
                })
            }
            ])
    }
]);

};

好的,我不得不对这个模型说几句话。

这是我复杂的 knockoutjs 模型。我应用它:

ko.applyBindings(new vm());

这个模型有 1 条“线”。 this.lines 是一个数组,可以容纳更多,但对于这个问题,这一行就足够了。

this.foods 和 this.meetings 是结果表的标题。该表如下所示:

| 2014                                                              | 2015
| until now                       | forecast                        | forecast
| pizza | burger | chilli | total | pizza | burger | chilli | total | pizza | burger | chilli | total |
|     1 |      0 |      1 |     0 |     3 |      2 |      5 |     0 |     2 |      2 |      3 |     0 |

这有点难以解释,但对于表格和虚拟机,我认为这是可以理解的 ;)

this.user/foods/meetings 是不可观察的,因为它们甚至不会在客户端发生变化。

正如您在 vm 中看到的,我的问题有一个 cmets。 在“总计”列中,我想要三种食物的总和。 (返回披萨+汉堡+辣椒) 但这不起作用,因为“this”不起作用。我无法访问这些值。

有人可以向我解释这个问题吗? 这个视图模型是好的做法吗?

我正在使用 knockout.js.3.1.0。

感谢您的回答 格鲁斯

P.S.:如果有人不明白这个问题,请问我;)

【问题讨论】:

  • 你应该定义子对象(元、会议值等),这有点乱
  • 你能不能把小提琴弄得更容易解释和调试+
  • @GoTo ok ;) 我会这样做...我会回来编辑帖子。

标签: javascript mvvm knockout.js viewmodel


【解决方案1】:

您有一个用于视图模型的普通 JS 对象。如果这样做,要正确计算和管理this 是相当困难的。我建议也为您的子视图模型使用构造函数,这将使这些(以及许多其他)问题和困难情况消失。这个KO documentation has some info。这也可以阐明self=this 的用途(您的主虚拟机的代码中有它,但不要使用它)。

如果你有/想要坚持使用普通的 JS 对象,那么我建议在创建主要的 observables 之后添加计算。像这样的:

this.lines = ko.observableArray([
    {   id: 1,
        meta: ko.observable(
            {   shop: ko.observable('foodstore'),
                tel: ko.observable('123 456'),
                url: ko.observable('foodstore24.com')
            }),
        meetingValues: ko.observableArray([
            {   productValues: ko.observableArray([
                    {productValue: ko.observable(1)},
                    {productValue: ko.observable(0)},
                    {productValue: ko.observable(1)}])
            }
            //etc
            ])
    }
]);

// See note, below code
this.lines()[0].meetingValues()[0].total = ko.computed(function() {
    //console.log(this.lines) -> expected: array output -> actual: undefined
    //console.log(this.lines()) -> expected: array output -> actual: error, this.lines() ist not a function
    //console.log(this) -> expected: this == self -> actual: this == self
    return 0;
}, this.lines()[0].meetingValues()[0]);

注意:上面的示例仅将total 设置为一个meetingValues,您必须使用循环将计算结果添加到所有它们中。这也是我建议对 View Models 使用构造函数的原因之一,因为它使管理 this 和计算更容易。

【讨论】:

  • thx,所以如果我定义“子对象”会使一切“更容易”?不,如果这很糟糕,我不想坚持使用普通的 JS 对象。我真的不使用“自我”......我只是将它包括在内以理解 vm 中的第三条评论。对我来说,“this”似乎是正确的,但“this”中没有“.lines”。计算中的 this/self.user 工作正常。简而言之:我必须将其移植到构造函数,还要制作“子”托管函数并将它们放入数组中? thx ...我会试试看;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 2015-10-31
  • 1970-01-01
相关资源
最近更新 更多