【问题标题】:knockout compute function - Cannot read property 'price' of null淘汰赛计算功能 - 无法读取 null 的属性“价格”
【发布时间】:2013-07-17 03:25:42
【问题描述】:

我正在尝试访问对象的属性,我知道该对象存在(并且具有我需要的属性),因为我可以将它记录到控制台。

但是,当我尝试访问它时,它显示无法读取 null 的属性“价格”。

我是一名 C# 开发人员,有点困惑,我一定是做错了什么,但我不知道是什么?从我的截图中,你可以看到返回的对象。

我的代码如下:

self.total = ko.computed(function(){
    var total = 0;      
    var selectedServerName = this.selectedServer();
    var selectedServerObject = ko.utils.arrayFirst(this.server, function(server){
        console.log("server.name = " + server.name);
        console.log("selectedServerName = " + selectedServerName);
        var serverCompare = (server.name == this.selectedServer());
        console.log("serverCompare is " + serverCompare);
    }, this);

    var selectedOsName = this.selectedOs();
    var selectedOsObject = ko.utils.arrayFirst(this.os, function(os){
        console.log("os.name = " + os.name);
        console.log("selectedOsName = " + selectedOsName);
        var osCompare = (os.name == this.selectedServer());
        console.log("osCompare is " + osCompare);
    }, this);

    total = total + selectedServerObject.price + selectedOsObject.price;

    return total;
},this);

更新

我更新的小提琴在这里:fiddle here

感谢 d.raev,当添加第二个日志行时出现 console.log(selectedServerObject.price,arrayFirst 函数开始以 selectedServer = undefined 调用。

server.name = DELL R210
selectedServerName = undefined
serverCompare is false
server.name = DELL R710
selectedServerName = undefined
serverCompare is false
server.name = DELL R720 Dual CPU
selectedServerName = undefined
serverCompare is false
os.name = Windows Standard
selectedOsName = undefined
osCompare is false
os.name = Windows Enterprise
selectedOsName = undefined
osCompare is false
os.name = CentOS Linux
selectedOsName = undefined
osCompare is false
os.name = Debian
selectedOsName = undefined
osCompare is false
1.  Uncaught TypeError: Cannot read property 'price' of null 

来自 selectedOsName 或 selectedServerName 的未定义值导致总计失败,它们被设置为未定义的原因是什么?

【问题讨论】:

  • “console.log(selectedServerObject.price)”的错误意味着 selectedServerObject 为空。因此,也许您在对象中拥有该行的任何上下文都已更改。
  • this.selectedServer() 不断返回undefined。你确定这是对的吗?
  • 请检查当前小提琴,jsfiddle.net/g18c/SMUSv/5Object {name: "DELL R210", specification: "1 x 2.4GHz Quad Core CPU<br/>4GB RAM<br/>2 x 300GB SAS 15k", price: 100} 已在第 205 行记录到控制台
  • @g18c 我添加了如何逃避错误的示例.. 但我不确定总的预期输出应该是什么。
  • @d.raev 非常感谢,总数应该包含多个字段,尽管真正的问题是测试方法中未定义的值来自哪里,但您已经一针见血了?

标签: knockout.js


【解决方案1】:

你的脚本运行了 2 次这个函数,添加第二个 Debug 显示更清晰:

var selectedServerObject = ko.utils.arrayFirst(this.server, function(server){
    console.log("server.name = " + server.name);
    console.log("selectedServer = " + this.selectedServer());
    return server.name ==  this.selectedServer();
}, this); 

输出:


server.name = DELL R210
selectedServer = 未定义
server.name = DELL R710
selectedServer = 未定义
server.name = DELL R720 双 CPU
selectedServer = 未定义
null (selectedServerObject)
...
server.name = DELL R210
selectedServer = DELL R210
对象{名称:“DELL R210”,规格:“1 x 2.4GHz 四核 CPU 4GB RAM
2 x 300GB SAS 15k”,价格:100}


只需添加一个检查 selectedServerObject 是否已设置 .. 或查找它被调用 2 次的原因:

示例:

if(selectedServerObject){
   total = total + selectedServerObject.price;
}

【讨论】:

  • 是 ko.utils.arrayFirst 不是一个实用程序,它需要一个函数返回一个布尔值来定义何时应该选择对象? knockmeout.net/2011/04/utility-functions-in-knockoutjs.htmlKnockout provides ko.utils.arrayFirst that will execute a function against each item in our array and return the first item where the function evaluates to true
【解决方案2】:

这里的小提琴http://jsfiddle.net/g18c/2SAxR/2/ 表明 d.raev 的怀疑是正确的 :) 我已经创建了原始代码的精简版本,当 selectedServer 未定义时调用描述计算函数,导致一切崩溃。

我已将 d.raev 的回复标记为答案,因为它找到了根本原因 - 很高兴了解这种 knockoutjs 行为以完全关闭。

<div data-bind="foreach: server">
    <div>
        <input type="radio" name="server" data-bind="attr: {value: sku}, checked: $root.selectedServer" />
        <span data-bind="text: name"></span>
    </div>
</div>
<p data-bind="text: selectedServer"></p>
<p data-bind="text: description"></p>

var serverOptions = [{
    name: "One",
    sku: 1000,
    specification: "yes",
    price: 100
}, {
    name: "Two",
    sku: 1001,
    specification: "hello",
    price: 200
}, {
    name: "Three",
    sku: 1002,
    specification: "wow",
    price: 300
}];

viewModel = function() {
    var self = this;
    self.server = serverOptions;
    self.selectedServer = ko.observable();
    self.description = ko.computed(function () {
        var selectedSku = this.selectedServer();
        if(typeof selectedSku == "undefined")
        {
            console.log("we are not fully bound, bombing out here...");
            return;
        }

        var found = ko.utils.arrayFirst(serverOptions, function (item) {
            var result = (item.sku == selectedSku);
            console.log("arrayFirst check => item.sku = " + item.sku + " selectedSku = " + selectedSku + ". result = " + result );
            return result;
        }, this);

        var textDescription = found.name + " - " + found.specification + " (" + found.price + ")";

        return textDescription;
    }, this);

    return self;
};

ko.applyBindings(new viewModel());

【讨论】:

    猜你喜欢
    • 2017-09-10
    • 1970-01-01
    • 2021-03-28
    • 2012-06-12
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多