1

I am trying to access a property of an object, I know the object exists (and has the property I need) as i can log it to the console.

However when i try and access it, it says Cannot read property 'price' of null.

I am a C# developer and little confused I must be doing something wrong but i do not know what? From my screenshot, you can see the object returned.

My code is below:

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);

Update

My updated fiddle is here: fiddle here

Thanks to d.raev it appears when the second log line is added console.log(selectedServerObject.price, the arrayFirst function starts being called with 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 

The undefined value from the selectedOsName or selectedServerName is causing the total to fail, what is the reason they are being set as undefined?

4

2 に答える 2

2

スクリプトはこの関数を 2 回実行します。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 = undefined
server.name = DELL R710
selectedServer = undefined
server.name = DELL R720 Dual CPU
selectedServer = undefined
null (selectedServerObject)
...
server.name = DELL R210
selectedServer = DELL R210
オブジェクト {name: 「DELL R210」、仕様:「1 x 2.4GHz クアッドコア CPU 4GB RAM
2 x 300GB SAS 15k」、価格:100}


selectedServerObject が設定されているかどうかのチェックを追加するか、2 回呼び出される理由を見つけます。

例:

if(selectedServerObject){
   total = total + selectedServerObject.price;
}
于 2013-07-18T09:10:56.877 に答える
0

ここでフィドルhttp://jsfiddle.net/g18c/2SAxR/2/は、d.raevの疑いが正しかったことを示しています:)元のコードのトリミングされたバージョンを作成しました.selectedServerが未定義の場合、記述計算関数が呼び出されます、すべてが爆破されます。

根本的な原因が見つかったため、d.raevの返信を回答としてマークしました-完全な閉鎖のためにこのノックアウトjsの動作を理解するといいでしょう。

<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());
于 2013-07-18T15:51:26.933 に答える