在Knockoutjs中引用子节点的计算属性

时间:2015-03-29 14:51:53

标签: knockout.js knockout-mapping-plugin

所以我有一个模特:

// Parent View Model
GameViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, resultItemMapping, self);

    self.PlayerCount = ko.computed(function () {
        return self.Results().length;
    });
};

使用这些映射它是孩子们:

var resultItemMapping = {
    'Results': {
        key: function (resultItem) {
            return ko.utils.unwrapObservable(resultItem.Id);
        },
        create: function (options) {
            return new ResultItemViewModel(options.data); 
        }
    }
};

// Child View Model
ResultItemViewModel = function (data) {
    var self = this;
    ko.mapping.fromJS(data, resultItemMapping, self);

    self.Points = ko.computed(function () {
        return (parent.PlayerCount);
    });
};

您可以看到游戏视图模型(父级)有一个名为PlayerCount(self.PlayerCount)的计算可观察对象,我可以成功将其绑定到我的视图,并根据结果的长度增加/减少accordinfly的数量(子) )收集。

问题在于子计算的可观察点称为Points(self.Points)。绑定到它的控件总是空的,如果我尝试做return (parent.PlayerCount * 10)之类的操作,我总是会返回NaN

理想情况下,根据玩家数量,结果项目总分数应为n * PlayerCount

显然我编码的内容无法正常工作,但我没有收到任何控制台错误消息。有没有更好的方法来做我想要实现的目标?

1 个答案:

答案 0 :(得分:1)

这很容易。 The mapping plugin provides the parent for you

var GameViewModel = function (data) {
    var self = this;

    self.Results = ko.observableArray();    
    self.PlayerCount = ko.pureComputed(function () {
        return self.Results().length;
    });

    ko.mapping.fromJS(data, GameViewModel.mapping, self);    
};
GameViewModel.mapping = {
    Results: {
        key: function (resultItem) {
            return ko.unwrap(resultItem.Id);
        },
        create: function (options) {
            return new ResultItemViewModel(options.data, options.parent); // <- here
        }
    }
};

var ResultItemViewModel = function (data, parent) {
    var self = this;

    self.Id = ko.observable();
    self.Points = ko.pureComputed(function () {
        return parent.PlayerCount();
    });

    ko.mapping.fromJS(data, ResultItemViewModel.mapping, self);
};
ResultItemViewModel.mapping = {
    // I can't imagine you want the same mapping definition as in the GameViewModel
};

请注意,我做了一些其他细微的更改,最突出的是使用pure computeds。我还想使viewmodel属性显式化,而不是完全依赖于映射插件。这可以防止代码访问不存在的属性,并且通常可以使调试更容易。