Knockout在hottowel SPA默认视图模型中计算了observable

时间:2013-03-26 22:19:01

标签: knockout.js durandal hottowel

我正在尝试在Hottowel SPA模板中的viewmodal模式之后创建一个简单的knockout计算observable。什么是最佳方式?

我最初有这样的事情:

define(['services/logger'], function (logger) {
    var vm = {
        activate: activate,
        title: 'Home View',
        testField: ko.observable("This is a test"),
        testComputedField: ko.computed(getComputed, this)
    };

    return vm;

    //#region Internal Methods
    function getComputed() {
        return "Computed: " + this.testField();
    }

    function activate() {
        logger.log('Home View Activated', null, 'home', true);
        return true;
    }
    //#endregion
});

但是这会导致错误,但我不能100%确定原因

TypeError: this.testField is not a function

因此,经过一些试验和错误,我得到了这个:

define(['services/logger'], function (logger) {
    var vm = {
        activate: activate,
        title: 'Home View',
        testField: ko.observable("This is a test")
    };

    vm.testComputedField = ko.computed(getComputed, vm);

    return vm;

    //#region Internal Methods
    function getComputed() {
        return "Computed: " + this.testField();
    }

    function activate() {
        logger.log('Home View Activated', null, 'home', true);
        return true;
    }
    //#endregion
});

但我不确定这是一个非常漂亮的方式吗?我显然没有很好地了解HotTowel中用于viewmodel的模块模式。所以我的问题是:

为什么我原来的方法不起作用? 有没有更好的或替代的方法来定义\结构视图模型而不是我的第二种方法?

2 个答案:

答案 0 :(得分:2)

Mutex,这是我正在使用的一般模式,它对我来说效果很好。

我为KO绑定使用函数表达式和局部作用域变量,并为Durandal特定方法(activated,viewAttached等)使用函数声明。 vm对象需要在函数表达式之后。消除了在任何地方使用'this'的需要。

define(['services/logger'], function (logger) {

    var testField = ko.observable("This is a test");

    var getComputed = ko.computed(function () {
        return "Computed: " + testField();
    });

    function activate() {
        logger.log('Home View Activated', null, 'home', true);
        return true;
    }

    var vm = {
        activate: activate,
        title: 'Home View',
        testField: testField,
        testComputedField: getComputed
    };

    return vm;
});

注意:这适用于HotTowel SPA模板

答案 1 :(得分:0)

您原来的方法:

var vm = {
   activate: activate,
   title: 'Home View',
   testField: ko.observable("This is a test"),
   testComputedField: ko.computed(getComputed, this)
};

当您将this传递给计算出来的时候this并未指向您的vm。而是传递vm本身:

var vm = {
   activate: activate,
   title: 'Home View',
   testField: ko.observable("This is a test"),
   testComputedField: ko.computed(getComputed, vm)
};

编辑 * * 我不知道上面为什么不起作用。根据淘汰文档,第二个参数应该将this上下文设置为第一个参数中的方法。尝试这个怎么样:

function getComputed() {
   return "Computed: " + vm.testField();
}