如何使用一个类为迪朗达尔我的壳视图模型?(How can I use a class for my

2019-08-18 09:02发布

我有一个看看热毛巾模板,并试图让它在打字稿工作中,我遇到了一个问题转换壳视图模型。 我试着翻译成TS这一点,它更有意义,我认为这应该是一个类,如图所示,而不是简单地导出函数在这里 。 我看着这个方法 ,但是,要注意的意见在这里 ,决定不跟随它。

有点挖后,我发现这个线程 ,这表明它应该是作为压倒一切的简单router.getActivatableInstance ,但我似乎无法获得足够远为函数曾经被调用。

这里是我的main.ts (一类也包裹起来):

/// <reference path="dts/toastr.d.ts" />
/// <reference path="dts/durandal.d.ts" />
/// <reference path="dts/require.d.ts" />

import _app = module('durandal/app');
import _system = module('durandal/system');
import _viewLocator = module('durandal/viewLocator');
import _router = module('durandal/plugins/router');
import _logger = module('services/logger');

export class HOPS {

    public init(): void {
        _logger.log('init', this, 'HOPS', false);
        _system.debug(true);
        this._startApp();
    }

    private _startApp(): void {
        _logger.log('_startApp', this, 'HOPS', false);

        _app.start().then(() => {
            toastr.options.positionClass = 'toast-bottom-right';
            toastr.options.backgroundpositionClass = 'toast-bottom-right';

            var defImpl = _router.getActivatableInstance; //default Implementation

            _router.getActivatableInstance = function (routeInfo: _router.routeInfo, paramaters: any, module: any) {
                var functionName = routeInfo.name.substring(0, 1).toUpperCase() + routeInfo.name.substring(1);
                if (typeof module [functionName] == 'function') {
                    var instance = new module [functionName]();
                    instance.__moduleId__ = module.__moduleId__;
                    return instance;
                }
                else return defImpl(routeInfo, paramaters, module );
            }

            _router.handleInvalidRoute = (route: _router.routeInfo, paramaters: any) => {
                _logger.logError('No Route Found', route, 'main', true);
            }

            _router.useConvention();
            _viewLocator.useConvention();

            _app.adaptToDevice();

            _app.setRoot('viewmodels/shell', 'entrance');
        });
    }
}

var hops: HOPS = new HOPS();
hops.init();

(游乐场表示这里JS: http://bit.ly/WyNbhn )

......这是我的shell.ts

import _system = module('durandal/system');
import _router = module('durandal/plugins/router');
import _logger = module('services/logger');

export class Shell{

    public router = _router;

    public activate(): JQueryPromise {
        _logger.log("activate", null, 'shell', false);
        return this.boot();
    }

    public boot(): JQueryPromise {
        _logger.log("boot", null, 'shell', false);
        this.router.mapNav('home')
        this.router.mapNav('details');
        _logger.log('SciHops SPA Loaded!', null, _system.getModuleId(this), true);
        return this.router.activate('home');
    }
}

...这编译为:

define(["require", "exports", 'durandal/system', 'durandal/plugins/router', 'services/logger'], function(require, exports, ___system__, ___router__, ___logger__) {
    /// <reference path="../dts/_references.ts" />
    var _system = ___system__;

    var _router = ___router__;

    var _logger = ___logger__;

    var shell = (function () {
        function shell() {

            this.router = _router;
        }
        shell.prototype.activate = function () {
            _logger.log("activate", null, 'shell', false);
            return this.boot();
        };
        shell.prototype.boot = function () {
            _logger.log("boot", null, 'shell', false);
            this.router.mapNav('home');
            this.router.mapNav('details');
            _logger.log('SciHops SPA Loaded!', null, _system.getModuleId(this), true);
            return this.router.activate('home');
        };
        return shell;
    })();
    exports.shell = shell;    
})

通过上面的类,我得到一个绑定错误,因为router是不确定的。 如果我加export var router = _router那么这个错误就会消失,但在我的壳类的激活方法不会被调用。

所有上述工作以及后续的ViewModels的,只是跌倒在外壳上。

我在做什么错了,我怎样才能得到一个TS类工作作为我的壳迪朗达尔视图模型?

Answer 1:

问题是你的路由器没有解决您的shell.ts模块。

您的所有其他的ViewModels在穿过router.getActivatableInstance方法和被实例化并具有__moduleId__贴给他们。 除非你shell.ts模块。

这是一个快速和肮脏的方式让您shell.ts模块工作。

你里面main.ts你可以要求你的shell.ts模块:

import _shell = module('shell');

然后,还是你的内main.ts你可以实例化你的shell类,并为其分配的moduleId。

var shell = new _shell.Shell();
shell.__moduleId__ = _shell.__moduleId__;
_app.setRoot(shell, 'entrance');

不是最漂亮的事情,你见过。 但它能够完成任务。 那几乎做的同样的事情getActivatableInstance重写你做的。由于,你的shell不经过router.js模块,你必须做手工。



Answer 2:

另一种选择是对类导出为Duranal模块。 注意:此方法也适用于的ViewModels。

基于的NuGet的“迪朗达尔入门工具包”工作的示例:

    import router = require('plugins/router')
    import app = require('durandal/app')

    class Shell {
        router =  router;
        public search() {
            //It's really easy to show a message box.
            //You can add custom options too. Also, it returns a promise for the user's response.
            app.showMessage('Search not yet implemented...');
        }
        public activate() {
            router.map([
                { route: '', title: 'Welcome', moduleId: 'viewmodels/welcome', nav: true },
                { route: 'flickr', moduleId: 'viewmodels/flickr', nav: true },
            ]).buildNavigationModel();


            return router.activate();
        }
    }

    // Magic happens here:
    export = Shell;

原来的“JS”的代码:

    define(['plugins/router', 'durandal/app'], function (router, app) {
        return {
            router: router,
            search: function() {
                //It's really easy to show a message box.
                //You can add custom options too. Also, it returns a promise for the user's response.
                app.showMessage('Search not yet implemented...');
            },
            activate: function () {
                router.map([
                    { route: '', title:'Welcome', moduleId: 'viewmodels/welcome', nav: true },
                    { route: 'flickr', moduleId: 'viewmodels/flickr', nav: true },
                ]).buildNavigationModel();


                return router.activate();
            }
        };
    });


文章来源: How can I use a class for my shell viewmodel in Durandal?