Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript KnockoutJS计算可观测未定义_Javascript_Knockout.js - Fatal编程技术网

Javascript KnockoutJS计算可观测未定义

Javascript KnockoutJS计算可观测未定义,javascript,knockout.js,Javascript,Knockout.js,我有一个非常简单的knockoutjs脚本。我的视图模型包含一个名为“modules”的属性,它是一个字符串数组。如果我有这样一个foreach列表,它会为每个项目打印一个模块列表: <tbody data-bind="foreach: items"> <tr> <td data-bind="text: modules"></td> </tr> </tbody> 我不确定,但如果你这样做会怎

我有一个非常简单的knockoutjs脚本。我的视图模型包含一个名为“modules”的属性,它是一个字符串数组。如果我有这样一个foreach列表,它会为每个项目打印一个模块列表:

<tbody data-bind="foreach: items">
    <tr>
        <td data-bind="text: modules"></td>
    </tr>
</tbody>

我不确定,但如果你这样做会怎么样:

function AppViewModel(data) {
    var self = this;
    ko.mapping.fromJS(data, {}, this);
    this.numModules = ko.computed(function() {
        return self.modules().length;
    });
};

$.getJSON("/api/items", function(data) {
    var viewModel = new AppViewModel(data);
    ko.applyBindings(viewModel);
});
function AppViewModel(data) {
    var self = this;

    this.modules = ko.obeservableArray();

    ko.mapping.fromJS(data, {}, this.modules());

    this.numModules = ko.computed(function() {
        return self.modules().length;
  });
};

我不确定,但如果你这样做会怎么样:

function AppViewModel(data) {
    var self = this;
    ko.mapping.fromJS(data, {}, this);
    this.numModules = ko.computed(function() {
        return self.modules().length;
    });
};

$.getJSON("/api/items", function(data) {
    var viewModel = new AppViewModel(data);
    ko.applyBindings(viewModel);
});
function AppViewModel(data) {
    var self = this;

    this.modules = ko.obeservableArray();

    ko.mapping.fromJS(data, {}, this.modules());

    this.numModules = ko.computed(function() {
        return self.modules().length;
  });
};

在这种情况下,可能是计算对象试图在属性实际存在之前进行计算。默认情况下,ko.computed上未设置的一个参数是deferEvaluation参数……设置此参数后,computed将不会尝试在AppViewModel初始化时进行计算

this.numModules = ko.computed({ 
    read: function() {
        return self.modules().length;
    },
    deferEvaluation: true
);

更为挑剔的是,如果您定义了“self=this”,那么在下一行中使用“this”的上下文设置您的计算,为什么要定义“self”?

在这种情况下,可能是计算程序在属性实际存在之前尝试计算。默认情况下,ko.computed上未设置的一个参数是deferEvaluation参数……设置此参数后,computed将不会尝试在AppViewModel初始化时进行计算

this.numModules = ko.computed({ 
    read: function() {
        return self.modules().length;
    },
    deferEvaluation: true
);

更为挑剔的是,如果您定义“self=this”,那么在下一行中,使用“this”上下文设置您的计算结果,为什么要定义“self”?

问题在于,您在ViewModel的上定义
numModules
,而您试图执行的计算是在每个
项的
模块
属性上进行的

因此,
self.modules
确实是未定义的,无法调用,因为
self
引用根对象,而
modules
是每个项的属性

请尝试以下方法:

function AppViewModel(data)
{
    var self = this;
    ko.mapping.fromJS(data, {}, this);

    // defining the computed function on each 'item'
    for (var i in self.items())
    {
        self.items()[i].numModules = ko.computed(function()
        {
            return this.modules().length;
        }, self.items()[i]);
    }
};
或者这样:

// defined on $root
self.numModules = function(item) {
    return item.modules().length;
}

// but passing 'item' upon invocation
<td data-bind="text: $root.numModules($data)"></td>
//在$root上定义
self.numModules=函数(项){
返回项.modules().length;
}
//但在调用时传递“项”

问题在于,您在ViewModel的上定义
numModules
,而您试图执行的计算是在每个
项的
模块
属性上进行的

因此,
self.modules
确实是未定义的,无法调用,因为
self
引用根对象,而
modules
是每个项的属性

请尝试以下方法:

function AppViewModel(data)
{
    var self = this;
    ko.mapping.fromJS(data, {}, this);

    // defining the computed function on each 'item'
    for (var i in self.items())
    {
        self.items()[i].numModules = ko.computed(function()
        {
            return this.modules().length;
        }, self.items()[i]);
    }
};
或者这样:

// defined on $root
self.numModules = function(item) {
    return item.modules().length;
}

// but passing 'item' upon invocation
<td data-bind="text: $root.numModules($data)"></td>
//在$root上定义
self.numModules=函数(项){
返回项.modules().length;
}
//但在调用时传递“项”

我发现解决这个问题的最简单方法是在html中这样做,而不添加任何特殊的js代码:

<td data-bind="text: modules().length"></td>

我发现解决这个问题的最简单方法是在html中这样做,而不添加任何特殊的js代码:

<td data-bind="text: modules().length"></td>


在您的AppViewModel中,您没有
模块
。这个想法是通过使用映射插件,模型由数据定义。在您的AppViewModel中,您没有
模块
。这个想法是通过使用映射插件,模型由数据定义。在您的第一个示例中,我希望避免在每个项目上定义函数。我宁愿以某种方式在模型上定义它。在最后一个示例中,函数真的与ko.computed相同吗?在
ko.computed
上使用函数是很常见的,在您的情况下也可以正常工作。有关更多信息,请参阅。在迄今为止的答案中,您的最后一个答案是唯一有效的。html中的$root和$data语法看起来并不像简单的“numModules”那么好。如果您想要的是漂亮干净的代码,最好是实际定义您的项目视图模型(
function item(){this.modules=…}
)不要依赖
ko.mapping
从任意数据动态创建对象。在第一个示例中,我希望避免在每个项上定义函数。我宁愿以某种方式在模型上定义它。在最后一个示例中,函数真的与ko.computed相同吗?在
ko.computed
上使用函数是很常见的,在您的情况下也可以正常工作。有关更多信息,请参阅。在迄今为止的答案中,您的最后一个答案是唯一有效的。html中的$root和$data语法看起来并不像简单的“numModules”那么好。如果您想要的是漂亮干净的代码,最好是实际定义您的项目视图模型(
function item(){this.modules=…}
)不要依赖于
ko.mapping
从任意数据动态创建对象。我明白了…仍然没有理由不在别处使用self,因为已经定义了它。我明白了…仍然没有理由不在别处使用self,因为已经定义了它。