制作没有new关键字的javascript knockout viewmodel

时间:2012-03-16 20:29:54

标签: javascript knockout.js viewmodel

我正在查看淘汰教程,所有示例都使用'new'关键字创建视图模型:

//from learn.knockoutjs.com
function AppViewModel() {
  this.firstName = ko.observable("Bert");
  this.lastName = ko.observable("Bertington");
  this.fullName = ko.computed(function() {
    return this.firstName() + " " + this.lastName();    
  }, this);
}
ko.applyBindings(new AppViewModel());

我正在尝试避免使用new关键字,这通常可以正常工作,但我发现使fullName computed属性工作有困难。这就是我到目前为止所提出的。

function makeViewModel() {
  return {
  firstName: ko.observable("Bert"),
  lastName: ko.observable("Bertington"),
  fullName: ko.computed(function() {
    return this.firstName() + " " + this.lastName();    
  }, this) };
}
ko.applyBindings(makeViewModel());

...显然失败,因为'this'不再引用传递给computed的函数内的局部对象。我可以通过创建变量并在附加计算函数并返回之前存储视图模型来解决这个问题,但是如果存在更优雅和紧凑的解决方案,则不需要我确保相互依赖的方法是按照正确的顺序附上,我肯定想用它来代替。

有更好的解决方案吗?

3 个答案:

答案 0 :(得分:5)

你可以通过自动调用函数来使用new关键字,但我认为你最好解决“this”关键字的问题。我想向人们展示3种创建视图模型的方法。

  1. object literal http://jsfiddle.net/johnpapa/u9S93/
  2. 作为函数http://jsfiddle.net/johnpapa/zBqxy/
  3. 使用揭示模块模式http://jsfiddle.net/johnpapa/uRXPn/
  4. 使用上面的选项2或3时,处理“this”关键字要容易得多。

答案 1 :(得分:3)

在函数中创建它时,不必返回新对象。相反,你会这样做:

var ViewModel = function() {
    this.firstName = ko.observable("Bert");
    this.lastName = ko.observable("Bertington");
    this.fullName = ko.computed(function() {
         this.firstName() + " " + this.lastName();
    }, this);
};

现在您可以在计算的observable中访问正确的内容。

如果你真的不想使用“新”(在这种情况下没有理由你不应该这样做),那么你可以这样做:

var createViewModel = function() { 
    var result = {
        firstName: ko.observable("Bert"),
        lastName: ko.observable("Bertington")
    };

    result.fullName = ko.computed(function() {
        return result.firstName() + " " result.lastName();
    });

    return result;
};

答案 2 :(得分:0)

你可以强制执行新的(取自this great pattern resource

function Waffle() {
    if (!(this instanceof Waffle)) {
    return new Waffle();
    }

    this.tastes = "yummy";
}

但我不确定你的意思

  

我正在尝试避免使用通常有效的新关键字   完全没问题,但我发现很难得到fullName计算   工作的财产。这就是我到目前为止所提出的。

这应该可以正常工作,你能告诉我们jsfiddle中一个不能使用new的具体例子。

希望这有帮助。