2013-03-26 95 views
1

我正試圖在Hottowel SPA模板中的viewmodal模式之後創建一個簡單的挖空計算observable。什麼是最好方式做到這一點?在hottowel SPA中計算可觀察的敲除默認視圖模型

我本來是這樣的:

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中熟練使用視圖模型的模塊模式。所以我的問題是:

爲什麼我的原始方法不工作? 有沒有比我的第二種方法更好或替代方式來定義\構建視圖模型?

回答

2

互斥量,這是我使用的一般模式,它對我很好。

我使用函數表達式和本地作用域變量作爲KO綁定,以及Durandal特定方法(激活,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模板

+0

謝謝,這看起來像一個更好的方法。 – mutex 2013-03-29 08:42:14

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

編輯* * 我不知道爲什麼上面沒有奏效。根據knockout文檔,第二個參數應該將this上下文設置爲第一個參數中的方法。試試這個怎麼樣:

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

不幸的是有相當多的傳球同樣的效果「這一」事實上,如果我把一個斷點在getComputed功能在第一線該函數的情況「this」最終成爲窗口對象。 – mutex 2013-03-27 01:29:21

+0

請參閱我的修訂。 – 2013-03-27 01:52:06

+0

這會導致將視圖模型定義爲對象字面量時出現的一些複雜問題。使對象文字工作的關鍵是分別定義你的屬性和函數,然後在最後建立你的對象,類似於mikekidder的答案。另一種方法是將視圖模型定義爲函數,正常顯示屬性和函數,並從模塊中返回該函數的新實例。 – 2013-03-27 14:03:21