我正在查看Hot Towel模板,并试图让它在TypeScript中工作,我遇到了转换shell viewmodel的问题。我试图将其转换为TS,对我来说更有意义的是它应该是一个类,而不是简单地导出如here所示的函数。我查看this approach但是,注意评论here,决定不遵守它。
经过一番挖掘后,我找到了this thread,这表明它应该像覆盖router.getActivatableInstance
一样简单,但我似乎无法远远地调用该函数。< / p>
这是我的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
,那么这个bug就会消失,但我的shell类上的activate方法永远不会被调用。
以上所有这些都适用于后续的视图模型,但只是落在shell上。
我做错了什么,如何让TS类作为我的shell Durandal viewmodel工作?
答案 0 :(得分:4)
问题是您的路由器没有解析您的shell.ts
模块。
所有其他视图模型都通过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
模块,你必须手动完成。
答案 1 :(得分:3)
另一种选择是将类导出为Duranal的模块。 注意:此方法也适用于视图模型。
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;
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();
}
};
});