2

这适用于让子菜单在主视图中工作。

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

有关源代码,请参阅我帖子顶部的链接。这个链接问题的答案包含一个我用来将此功能集成到热毛巾项目中的示例。

4

2 回答 2

2

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

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

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

这是修改后的 about/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 是 ctor。像下面这样的 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;
});
于 2013-05-11T16:26:45.557 回答
0

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

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

所以你必须创建一个完整的激活器来控制子菜单。以https://github.com/BlueSpire/Durandal/blob/master/App/samples/knockout/index.js#L6为例。

简而言之:

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

    return {
        activeSample:viewModel.activator(),
        ...  
于 2013-05-09T19:47:05.840 回答