使用每个system.acquire获取一个持久化视图模型的新实例

Get a new instance of a durandal viewmodel with every system.acquire

本文关键字:视图 模型 新实例 实例 持久化 system acquire 获取 一个      更新时间:2023-09-26

我正在使用热毛巾模板,我正在尝试动态加载视图到仪表板类型的视图。

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

假设我有一个图形视图。我希望能够像这样导航到它:"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和/或require的正确用法。但是,对于相同类型的每个视图,acquire方法返回的模型是相同的。组成仪表板的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 widgets?但我想让它们成为仪表板上的普通视图和"小部件"。我如何用更简洁的方式解决这个问题?

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

主细节样本清楚地说明了这一点。更改了视图模型,以便在示例中使用原型模式。然后使用视图模型。

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

仪表板激活

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>