使用计算的可观察对象进行对象作用域

时间:2014-05-15 17:55:29

标签: javascript knockout.js

我目前正在使用computed observables在对象范围内进行搜索,并希望有人可以帮助我!

JSFIDDLE DEMO

基本上,我有一个对象(简单说明问题):

var viewModel = {
    firstName: ko.observable('John'),
    lastName: ko.observable('Doe'),
    fullName: ko.computed(function(){
        return this.firstName() + ' ' + this.lastName();
    }, this)
};

我想引用当前的对象属性,因此我执行以下操作:

fullName: ko.computed(function(){
    return this.firstName() + ' ' + this.lastName();
 }, this);
      ^------- thought 'this' would refer to 'viewModel'

现在,我认为this会引用我的对象viewModel,而是指window

因此,由于"Uncaught TypeError: undefined is not a function"没有方法windowfirstName(),因此会引发错误lastName()

HTML:

<div>
    <strong>First Name:</strong>
    <span data-bind="text: firstName"></span>

    <strong>Last Name:</strong>
    <span data-bind="text: lastName"></span>

    <strong>Full Name:</strong>
    <span data-bind="text: fullName"></span>
</div>

JS:

var viewModel = {
    firstName: ko.observable('John'),
    lastName: ko.observable('Doe'),
    fullName: ko.computed(function(){
        // this = window
        // when using -- this.firstName() + ' ' + this.lastName()
        // it will throw Uncaught TypeError: undefined is not a function"

        // return this.firstName() + ' ' + this.lastName();
    }, this)
};

ko.applyBindings(viewModel);

尽管如此,我还有以下问题

  • 为什么this引用window而不是对象本身?
  • 如何将其范围扩展到对象 - 没有 viewModel视为一种功能?

非常感谢任何帮助!

编辑:

我知道这可以通过将viewModel视为一个函数来完成,但是,我想知道是否可以使用对象?

4 个答案:

答案 0 :(得分:2)

也可以这样做(演示:http://jsfiddle.net/QLwj2/

var viewModel = {};

    viewModel.firstName = ko.observable('John');
    viewModel.lastName = ko.observable('Doe');
    viewModel.fullName = ko.computed(function(){
        return viewModel.firstName() + ' ' + viewModel.lastName();
    });

答案 1 :(得分:2)

吃你的单身蛋糕并吃掉它。

var viewModel = new function() {
    // Note that the anonymous function is instantiated via new,
    // effectively returning a singleton.
    this.firstName = ko.observable('John');
    this.lastName = ko.observable('Doe');
    this.fullName = ko.computed(function(){
        return this.firstName() + ' ' + this.lastName();
    }, this);
}();

ko.applyBindings(viewModel);

答案 2 :(得分:1)

this并不意味着您的视图模型,因为您不在范围内,因为您不在函数内部,而是使用对象表示法而不是函数。如果您将代码更改为:

var ViewModel = function() {
    this.firstName= ko.observable('John');
    this.lastName= ko.observable('Doe');
    this.fullName= ko.computed(function(){
        // this = window
        // when using -- this.firstName() + ' ' + this.lastName()
        // it will throw Uncaught TypeError: undefined is not a function"

        // return this.firstName() + ' ' + this.lastName();
    }, this);
}

var viewModel = new ViewModel();

然后它应该工作,因为你正在创建一个范围,因此this指的是当前的范围。

答案 3 :(得分:1)

function AppViewModel() {
    var self = this;

    self.firstName = ko.observable('Bob');
    self.lastName = ko.observable('Smith');
    self.fullName = ko.computed(function() {
        return self.firstName() + " " + self.lastName();
    },self);
}

为避免混淆这些关键字,使用self是一种更好的方法。因为self是在函数的闭包中捕获的,所以它在任何嵌套函数中都是可用且一致的,例如ko.computed赋值器。这个约定在事件处理程序中更有用,正如您将在许多实例中看到的那样。

我从knockoutjs 文档中获取了这个。