Durandal Custom View Location Strategy

痞子三分冷 提交于 2019-12-07 04:50:22

问题


I am trying to figure out how to use a custom view location strategy, I have read the documentation at this page http://durandaljs.com/documentation/Using-Composition/ but I don't exactly understand what the strategy function should look like.

Can anybody give me a quick example of what the implementation of this function would be like and the promise that returns (even a simple one) etc?

Thanks in advance, Gary

p.s. This is the code in my html:

 <div>
     <div data-bind="compose: {model: 'viewmodels/childRouter/first/simpleModel', strategy:
 'viewmodels/childRouter/first/myCustomViewStrategy'}"></div> </div>

and this is the code in my myCustomViewStrategy:

define(function () {

    var myCustomViewStrategy = function () {

        var deferred = $.Deferred();

        deferred.done(function () { console.log('done'); return 'simpleModelView'; });
        deferred.fail(function () { console.log('error'); });

        setTimeout(function () { deferred.resolve('done'); }, 5000);

        return deferred.promise();
    };

return myCustomViewStrategy;
});

but I get the error:

Uncaught TypeError: Cannot read property 'display' of undefined - this is after done has been logged in the console window.


回答1:


Okay I solved this by creating my custom view strategy by the following:

define(['durandal/system', 'durandal/viewEngine'], function (system, viewEngine) {

    var myCustomViewStrategy = function () {
        return viewEngine.createView('views/childRouter/first/sModelView');
    }

    return myCustomViewStrategy;

});



回答2:


As I found the documentation a bit lacking on compose binding's strategy setting I checked the source code how it works. To summ it up:

The module specified by the compose binding's strategy setting by its moduleId

  • must return a function named 'strategy'
  • which returns a promise which results in the view to be bound
  • as a HTML element object.
  • As a parameter the strategy method receives the compose binding's settings object
  • with the model object already resolved.

A working example:

define(['durandal/system', 'durandal/viewEngine'], function (system, viewEngine) {

    var strategy = function(settings){
        var viewid = null;
        if(settings.model){
            // replaces model's module id's last segment ('/viewmodel') with '/view'
            viewid = settings.model.__moduleId__.replace(/\/[^\/]*$/, '/view');
        }
        return viewEngine.createView(viewid);
    };

    return strategy;
});  

Durandal's source:

// composition.js:485

for (var attrName in settings) {
    if (ko.utils.arrayIndexOf(bindableSettings, attrName) != -1) {
        /*
         * strategy is unwrapped
         */
        settings[attrName] = ko.utils.unwrapObservable(settings[attrName]);
    } else {
        settings[attrName] = settings[attrName];
    }
}

// composition.js:523

if (system.isString(context.strategy)) {
    /*
     * strategy is loaded
     */
    system.acquire(context.strategy).then(function (strategy) {
        context.strategy = strategy;
        composition.executeStrategy(context);
    }).fail(function(err){
        system.error('Failed to load view strategy (' + context.strategy + '). Details: ' + err.message);
    });
} else {
    this.executeStrategy(context);
}

// composition.js:501

executeStrategy: function (context) {
    /*
     * strategy is executed
     * expected to be a promise
     * which returns the view to be bound and inserted to the DOM
     */
    context.strategy(context).then(function (child) {
        composition.bindAndShow(child, context);
    });
}


来源:https://stackoverflow.com/questions/20566153/durandal-custom-view-location-strategy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!