【问题标题】:Unable to get correct knockout binding context无法获得正确的淘汰赛绑定上下文
【发布时间】:2013-12-08 11:06:16
【问题描述】:

我有以下 javascript 用于我的淘汰赛绑定。

var context = this;

var viewModel = {
    lineitems: [{
        quantity: ko.observable(1),
        title: 'bar',
        description: 'foo',
        price: ko.observable(10),
        total: ko.observable(10),
        formattedTotal: ko.computed({
        read: function () { 
            return '$' + this.price().toFixed(2);
        },
        write: function (value) { 
            value = parseFloat(value.replace(/[^\.\d]/g, ""));
            this.price(isNaN(value) ? 0 : value);
        } 
       })
    }]
};

ko.applyBindings(viewModel);

按预期绑定,但是当我应用 formattedTotal 时,我收到以下 javascript 错误。

Uncaught TypeError: Object [object global] has no method 'price'

我尝试了一些语法更改,但我似乎无法正确,我哪里出错了?

【问题讨论】:

  • 你确定这是正确的小提琴吗?
  • 完全错了。谢谢

标签: javascript knockout.js


【解决方案1】:

问题在于您的 formattedTotal 方法:范围 - this - 不是您的 viewModel。试试这个:

var viewModel = {
    lineitems: [{
        quantity: ko.observable(1),
        title: 'bar',
        description: 'foo',
        price: ko.observable(10),
        total: ko.observable(10),
        formattedTotal: ko.computed({
        read: function () { 
            return '$' + viewModel.lineitems.price().toFixed(2);
        },
        write: function (value) { 
            value = parseFloat(value.replace(/[^\.\d]/g, ""));
            viewModel.lineitems.price(isNaN(value) ? 0 : value);
        } 
       })
    }]
};

考虑为您的视图模型使用构造函数而不是对象字面量;这使得处理范围问题更容易和更清晰。示例见this answer

【讨论】:

    【解决方案2】:

    通常在 JavaScript 中使用 this 并不是一个好主意。尤其是淘汰赛。你永远不知道this在执行期间会是什么。

    所以我建议这样写:

    function LineItem(_quantity, _title, _description, _price) {
        var self = this;
    
        self.quantity = ko.observable(_quantity);
        self.title = ko.observable(_title);
        self.description = ko.observable(_description);
        self.price = ko.observable(_price);
    
        self.total = ko.computed(function () {
            return self.price() * self.quantity();
        }, self);
    
        self.formattedTotal = ko.computed(function () {
            return '$' + self.total().toFixed(2);
        }, self);
    };
    
    var viewModel = {
        lineItems: [
        new LineItem(10, 'Some Item', 'Some description', 200),
        new LineItem(5, 'Something else', 'Some other desc', 100)
    ]
    };
    
    ko.applyBindings(viewModel);
    

    你可以阅读一些关于self=this模式here.的讨论

    【讨论】:

      猜你喜欢
      • 2013-12-11
      • 2013-01-01
      • 2014-11-29
      • 2016-01-22
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      相关资源
      最近更新 更多