【问题标题】:Get a new instance of a durandal viewmodel with every system.acquire使用每个 system.acquire 获取 durandal 视图模型的新实例
【发布时间】:2013-05-29 13:41:35
【问题描述】:

我正在使用 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 和/或正确的要求。但是acquire方法返回的模型对于同类型的每一个view都是一样的。组成仪表板的 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 绑定

    <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 小部件?但我希望将它们作为仪表板上的普通视图和“小部件”。如何以更简洁的方式解决此问题?

【问题讨论】:

    标签: javascript requirejs durandal


    【解决方案1】:

    我解决了。我找到了样本,呵呵。我忽略了文档中的那个链接。

    主细节样本说得很清楚。更改视图模型以使用示例中的原型模式。然后在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 绑定

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 2019-10-03
      相关资源
      最近更新 更多