Durandal激活,子路由器的分离事件永远不会被触发

时间:2016-02-12 17:46:17

标签: javascript knockout.js durandal durandal-2.0 durandal-navigation

使用以下Durandal 子路由器插件配置时,我未收到detachedactivate个事件described in the Durandal lifecycle,而其他活动有效。

这是一个单页面应用程序,其中childRouter容器的div控制内容。每个childRouter对应一个模块,一次只能有一个attached,而其他detached应该是childRouter

应用程序为每个模块使用单独的detached个实例,并且我希望每次在两个模块之间导航时activatemoduleOLD事件被触发(即{{{{ 1}}应该获得detachedmoduleNEW应该获得attached)。

文档说明Durandal生命周期事件会自动触发

  

突出显示为绿色的行将始终在撰写时执行。

它不会以这种方式工作,这可能是由以下原因引起的:

  • 儿童路由器未被通知关于彼此附加/分离(即需要订阅某些事件)
  • 子路由器工作方式比父路由器

我似乎必须手动分离,或通知正在被替换的路由器,以触发detachedactivate

如何触发detached的{​​{1}}和activate个事件?

childRouter

输出(无错误):

define([ 'durandal/app', 'plugins/router'], function(
        app, router) {
    var childRouter = router.createChildRouter();
    childRouter.makeRelative({
        moduleId : 'modules/moduleX/pages',
        fromParent : true
    });
    childRouter.map([ {
        route : [ '', 'grid' ],
        moduleId : 'grid/index',
    }, {
        route : 'details/:id',
        moduleId : 'details/index',
    }, {
        route : 'details/tabs/base',
        moduleId : 'details/tabs/base',
    } ]);
    childRouter.buildNavigationModel();
    childRouter.activate = function() {
        console.log("activate");//DOESN'T WORK
    };
    childRouter.attached = function() {
        console.log("attached");//WORKS
    };
    childRouter.compositionComplete = function() {
        console.log("compositionComplete");//WORKS
    };
    childRouter.detached = function() {
        console.log("detached");//DOESN'T WORK
    };
    return {
        router : childRouter
    };
});

1 个答案:

答案 0 :(得分:0)

在Durandal中,激活生命周期特定于 激活器 。每个路由器和子路由器在 activeItem 中都有一个,它还充当该路由器上当前激活的模块的访问者。

Durandal确保在每个 模块 上更改或即将更改任何当前活动路由器上的活动项时,正确调用生命周期中的事件,然后当/它将数据绑定到模块的视图并将其附加到DOM文档时。

要按预期触发事件,应在每个需要此类处理程序的模块上声明具有相应名称的方法。

激活在所有子路由器上进行,但是从根路由器开始逐步进行。因此,当为新路由选择模块时,根路由器将询问其当前活动模块是否 canDeactivate ,这将链接到其中的所有活动模块子路由器。然后它会询问新模块 canActivate 。如果两者都允许,激活将通过,根路由器上的活动项将发生变化,触发模块上的 取消激活/激活 方法(如果存在)。如果路由比匹配的片段多,并且激活的模块有子路由器,那么它上面的子路由也将被触发。

当在激活中重复使用相同的模块时,仍然会触发事件链,但可能会发生某些模块上的 取消激活 方法如果路由器没有从新路由接收匹配的模块,则子路由器中可能不会触发。例如,如果未将子路由器配置为空路由('')并且导航更改回父路由,例如从products/item/15返回到products,则会发生这种情况。没有新匹配且没有要切换到的新模块的路由器,这意味着无论父products匹配哪个父模块,仍然会在其子路由器上激活item 15的旧模块。为了避免在重用模块时出现这种情况,一种选择是始终在子路由器上配置空路由('')。如果有的话,将其与具有空白视图的模块匹配,例如空div