单页应用程序(SPA)与Durandaljs,不能加载默认路由

时间:2013-09-29 14:16:13

标签: durandal single-page-application durandal-navigation

我正在尝试编写一个NopCommerce插件。我已将我的app相关文件放在app命名目录中插件的根目录中。在我的 shell.js viewmodel中,我按如下方式定义路线:

define(['durandal/system', 'durandal/plugins/router', 'service/logger','config'],
    function(system, router, logger,config) {

        var shell = {
            activate: activate,
            router: router
        };

        function activate() {
            logger.log('MyProducts Started', null, system.getModuleId(shell), true);
            router.map([
                { route: '', moduleId: 'viewmodels/myProducts', title: 'My Products', nav: true },
                { route: 'searchProducts', moduleId: 'viewmodels/searchProduct', title: 'Search Products', nav: true },
                { route: 'addProducts', moduleId: 'viewmodels/addProduct', title: 'Add Product', nav: true }
            ]).buildNavigationModel();
            return router.activate();
        }

        return shell;
    }
);

按照惯例,它应该转到模块定义的第一个路由:viewmodels/myProducts但是我收到以下错误:

[viewmodels/shell] MyProducts Started system.js:75
[main] No router found Object
Navigation Complete undefined Object
Uncaught TypeError: Cannot read property 'router' of undefined 

我正在敲打我的头。它不会进入默认路线(路线:'')。

3 个答案:

答案 0 :(得分:3)

在路线导航期间遇到同样的问题。 原来是空的js模块文件 - 我制作了文件,但没有把任何东西放进去,并把它添加到路线。

因此,该消息可能意味着路由器获得了您作为路由控制器源引用的js文件之一,但无法从中获取页面控制器对象实例。

答案 1 :(得分:1)

已解决:)

经过一番头痛之后,我发现这导致了这个问题:

define([..., 'durandal/plugins/router',...]

当我删除它并解决后。

编辑: - 以下是我的main.js文件中的定义函数。

define(['durandal/system', 'durandal/app', 'durandal/viewLocator'
                                                            , 'service/logger'],
function (system, app, viewLocator, logger) {
    system.debug(true);

    app.configurePlugins({
        router: true,
        dialog: true,
        widget: true
    });

    app.start().then(function () {
        viewLocator.useConvention();
        app.setRoot('viewmodels/shell', 'entrance');

        //router.mapUnknownRoutes(function (instruction) {
        //    logger.logError('No router found', instruction, 'main', true);
        //});
    });
});

答案 2 :(得分:0)

不同意Durandal超级巨星的惯例,但我认为路由器信息根本不属于shell。从逻辑上讲,路由器是应用程序核心的一部分,因此属于main.js中的应用程序引导逻辑。以下是main.js中定义调用的典型示例:

define(function (require) {

    var system = require('durandal/system'),
        app = require('durandal/app'),
        viewLocator = require('durandal/viewLocator'),
        router = require('plugins/router');

    //>>excludeStart("build", true);
    system.debug(true);
    //>>excludeEnd("build");

    app.title = 'Durandal Starter Kit';
    app.configurePlugins({
        router: true,
        dialog: true
    });

    app.start().then(function() {
        router.map([
            { route: '', title: 'Welcome', moduleId: 'viewmodels/welcome' }
        ]).activate();
        viewLocator.useConvention();
        app.setRoot('viewmodels/shell', 'entrance');
    });
});

我很少使用导航模型功能,因此我不打算构建导航模型。除此之外,引导路由器是同步的,因此定义路由,激活路由器,然后加载shell就足够了。

如果您确实需要在shell中使用路由器,只需将依赖项添加到您的定义调用中

define([..., 'plugins/router', ...], function(..., router, ...) { ... });

define(function (require) { 
    var router = require('plugins/router');
    ...
});

此时已激活的路由器将暴露给您的shell。