我正在查看 Hot Towel 模板,并试图让它在 TypeScript 中工作,我在转换 shell View 模型时遇到了问题。我正在尝试将其转换为 TS,这对我来说更有意义,它应该是一个类,而不是像所示那样简单地导出函数 here .我看了this approach但是,注意评论here , 决定不遵循它。

经过一番挖掘,我找到了 this thread ,这表明它应该像重写 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 的 Playground :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;     
}) 

对于上面的类,我得到一个绑定(bind)错误,因为 router 是未定义的。如果我添加 export var router = _router 那么这个错误就会消失,但我的 shell 类上的激活方法永远不会被调用。

以上所有内容都适用于后续的 View 模型,但只是落在了 shell 上。

我做错了什么,如何让 TS 类作为我的 shell Durandal View 模型工作?

请您参考如下方法:

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

所有其他 View 模型都通过 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 模块,您必须手动完成。


评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!