Durandal Subrouting(Hottowel)生命周期回调

时间:2013-05-09 19:29:00

标签: knockout.js url-routing durandal hottowel

This works well,用于在主视图中使用子菜单。

我能够通过在compose绑定中添加activate:true来使activate()函数适用于子菜单视图模型。其他生命周期事件虽然没有开火。如何在我的子视图模型中使用canActivate(),canDeactivate()和deactivate()?

请参阅我帖子顶部的链接以获取源代码。这个链接问题的答案包含一个我用来将此功能集成到Hot Towel项目中的示例。

2 个答案:

答案 0 :(得分:2)

看起来@ evan-larsen构造inAbout激活器()的方式阻止执行canDeactivate和Deactivate事件。不知道为什么。

通过将其转换为使用system.acquire,我可以再次触发这些事件。

return system.acquire(convertSplatToModuleId(activationData.splat)).then(function( Sample ) {
       App.inAbout(new Sample());
   });

这是修改后的/ index.js。

define(
  ['durandal/system', 'durandal/viewModel', 'durandal/plugins/router'],
  function( system, viewModel, router ) {
      var defaultPage = 'aboutUs';

      function convertNameToModuleId ( name ) {
          return 'deepLinkingExample/areas/about/' + name + '/' + name;
      }

      function convertSplatToModuleId ( splat ) {
          if ( splat && splat.length > 0 ) {
              return convertNameToModuleId(splat[0]);
          }
          return convertNameToModuleId(defaultPage);
      }

      var App = {
          inAbout: viewModel.activator(),

          activate: function( activationData ) {

                  return system.acquire(convertSplatToModuleId(activationData.splat)).then(function( Sample ) {
                      App.inAbout(new Sample());
                  });
          },

          showPage: function( name ) {
              return function() {
                  router.navigateTo('#/about/' + name);
              };
          },

          isPageActive: function( name ) {
              var moduleName = convertNameToModuleId(name);
              return ko.computed(function() {
                    return this.inAbout().__moduleId__ === moduleName;
              }, this);
          }
      };

      return App;
  }
);

上面的代码假设您返回的详细VM是ctors。像下面这样的aboutMe.js应该这样做。

define(['durandal/app', 'durandal/system'], function (app, system) {

    var ctor = function() {
           this.name = "About me";
           this.description = "For demonstration only";
       };

       ctor.prototype.canActivate = function () {
           return app.showMessage('Do you want to view ' + this.name + '?', 'Master Detail', ['Yes', 'No']);
       };

       ctor.prototype.activate = function() {
           system.log('Model Activating', this);
       };

       ctor.prototype.canDeactivate = function () {
           return app.showMessage('Do you want to leave ' + this.name + '?', 'Master Detail', ['Yes', 'No']);
       };

       ctor.prototype.deactivate = function () {
           system.log('Model Deactivating', this);
       };

       return ctor;
});

答案 1 :(得分:0)

根据docs activate: true不会添加完整的生命周期事件

  

注意:案例3和案例4略有不同,因为它们只是强制执行   canActivate并激活回调;不是停用生命周期。至   启用它,您必须自己使用完整的激活器(情况1或2)。

因此,您必须创建一个控制子菜单的完整激活器。请查看https://github.com/BlueSpire/Durandal/blob/master/App/samples/knockout/index.js#L6示例。

简而言之:

define(['durandal/viewModel'], function (viewModel) {

    return {
        activeSample:viewModel.activator(),
        ...