使用每个system.acquire获取durandal viewmodel的新实例

时间:2013-05-29 13:41:35

标签: javascript requirejs durandal

我正在使用hottowel模板,并且我试图动态地将视图加载到仪表板类型视图。

视图也应该能够单独查看。

所以我想说我有一个图表视图。我希望能够像这样导航到它:" mysite.com /#/ graph / 1"。

我还应该能够通过ko绑定将视图组合到仪表板视图中。

我现在正在做的是在仪表板的激活方法上加载用户保存的仪表板视图。像这样:

仪表板激活

function activate() {

        return datacontext.getUserDashboardConfigurations(userId)
        .then(function (data) {

            _.each(data.elements(), function (view) {
                system.acquire("viewmodels/" + view.viewType()).then(function (model) {
                    var newModel =  model.create(); //factory method
                    newModel.__moduleId__ = model.__moduleId__;
                    newModel.viewSettingsId(view.SettingsId());
                    views.push(newModel);
                });
            });

            vm.showLoad(false);
        });
    }

我可能无法理解durandal和/或正确的要求。但是,获取方法返回的模型对于相同类型的每个视图都是相同的。组成仪表板的3个图表视图都获得了图模型的相同实例。所以我所做的是为模型创建一种工厂方法。

图表模型

define( function(logger, dataContext) {

    function model() {
        var viewSettingsId= ko.observable(0);      

        function activate() {
        //omitted
        }

        function viewAttached(view) {
            //omitted
        }

        return {
            activate: activate,         
            title: 'Graph View',
            viewSettingsId: viewSettingsId
        };
    }

    return {
        create: function() {
            return new model();
        }
    };
});

ko binding

    <div id="columns" data-bind=" foreach: views">
            <div  data-bind="compose: { model: $data, activate: true, alwaysAttachView: true, preserveContext: false } "></div>
    </div>

路由器被覆盖

  router.getActivatableInstance = function(routeInfo, params, module) {
        if (typeof module == 'function') {
            return new module();
        } else {
            if (module.create && typeof module.create == 'function') {
                var newModule = module.create();
                newModule.__moduleId__ = module.__moduleId__;

                return newModule;
            }
            return module;
        }
    };

这种解决了仪表板的问题。导航也有效。但我觉得必须有一个更好的解决方案。也许durandal小部件?但我希望将它们作为普通视图和&#34;小部件&#34;在仪表板上。如何以更清洁的方式解决这个问题?

1 个答案:

答案 0 :(得分:2)

我解决了。我找到了样品,呃。我忽略了文档中的链接。

主要细节样本清楚明了。更改了viewmodel以使用示例中的原型模式。然后在system.acquire之后使用viewmodel.activateItem。

然后像示例一样撰写视图。工作和感觉更干净!

仪表板激活

function activate() {
        return datacontext.getUserDashboardConfigurations(userId)
        .then(function (data) {

            currentDashboardconfiguration = data;

            _.each(data.elements(), function (view) {


                system.acquire("viewmodels/" + view.viewType()).then(function (model) {

                    var newModel = new model();

                    viewModel.activator().activateItem(newModel, { id: view.viewSettingsId() }).then(function (suc) {
                        views.push(newModel);
                    });
                });
            });

            vm.showLoad(false);
        });
}

图表模型

define( function(logger, dataContext) {


    var ctor = function()
    {
        this.viewSettingsId = ko.observable(0); 
        this.title: 'Graph View',  
    }

    ctor.prototype.activate = function() {
        //omitted
     }

    ctor.prototype.viewAttached = function(view) {
       //omitted
    }

    return ctor;
});

ko binding

<div id="columns" data-bind=" foreach: views">
    <div class="widget column" data-bind="compose: $data"></div>
</div>