如何将AMD模块从单例转换为实例?

时间:2013-10-28 17:24:38

标签: javascript knockout.js durandal

我正在尝试将工作的Durandal视图模型模块从单例转换为实例。原始工作版本遵循以下模式:

define(['knockout'],
function(ko) {

    var vm = {
        activate: activate,
        companyId: null;
        company: ko.observable({})
    };

    return vm;

    function activate(companyId) {
        vm.companyId = companyId;
        //get company data then
        vm.company(data);
    }
}

新版本导出一个函数,以便我在每个请求中获得一个新实例...

define(['knockout'],
function(ko) {

    var vm = function() {
        activate = activate;
        companyId = null;
        company = ko.observable({});
    };

    return vm;

    function activate(companyId) {
        vm.companyId = companyId;
        //get company data then
        vm.company(data);
    }
}

我得到的错误是“对象函数()[...函数签名...]在行vm.company(data);上没有方法公司。我做错了什么?为什么我可以设置属性但是无法访问knockout observable?我应该如何重构原始代码,以便每次请求都获得一个新实例?


我为简化此问题的代码所做的努力隐藏了实际问题。我真正的代码是使用Q promises并用Q.All调用两个方法。由于Q位于全局命名空间中,因此在转换为函数后无法解析我的viewmodel。将视图模型传递给Q调用的方法解决了问题。

3 个答案:

答案 0 :(得分:1)

以这种方式尝试:

var vm = function() {
        this.activate = activate;
        this.companyId = null;
        this.company = ko.observable({});
    };

没有任何限定符,这些关键字被分配给全局变量。

但是,如果此模块已被您无法轻易修改的代码使用,那么您可能会遇到问题,因为任何引用vm的内容都需要知道它是需要调用的函数。

答案 1 :(得分:1)

你应该这样重新考虑它:

define(['knockout'],
  function(ko) {

    var vm = function() {
      this.companyId = null;
      this.company = ko.observable({});
    };

    vm.prototype.activate = function (companyId) {
      this.companyId = companyId;
      //get company data then
      this.company(data);
    };

    return vm;
  }

答案 2 :(得分:1)

试试这个

define(['knockout'],
function(ko) {
var createVM = function() {
    var vm = {
    activate: activate,
    companyId: null;
    company: ko.observable({})
    }
    return vm;
};

。 var vm = createVM();     return vm;

function activate(companyId) {
    vm.companyId = companyId;
    //get company data then
    vm.company(data);
}
}