2014-12-29 124 views
1

这可能是代码结构的问题,而不是关于框架的问题。父路由器激活功能每次将子路由导航到?

基本上我想知道是否应该在父路由器上的激活函数每次导航到其子路由时调用?

我的目标: 有一个返回子路由器的模块,这是父路由器。如果用户正在添加新的东西,则该父路由器负责创建对象,或者如果用户选择了已存在的东西,则从服务器检索数据。子路由模块只需获取通过父路由器模块创建或检索的对象,并提供表单输入来操作该对象(通过ko数据绑定)。我遇到的问题是父路由器的激活函数在每次导航到子路由时都会被调用,这是创建/检索逻辑所在的位置,并且会再次检索对象,导致任何数据操作被覆盖。

下面是一些代码,希望能更好地说明:

// ParentRouter 
define([...], function(...) { 
    var selectedObj = ko.observable(null), 
     configRouter = router.createChildRouter() 
      .makeRelative({ 
       moduleId: 'viewmodels', 
       fromParent: true, 
       dynamicHash: ':id' 
      }).map([ 
       { 
        route: ['Settings 1', ''], 
        moduleId: 'SettingsOne', 
        nav: true 
       }, 
       { 
        route: 'Settings 2', 
        moduleId: 'SettingsTwo', 
        nav: true 
       }, 
       { 
        route: 'Settings 3', 
        moduleId: 'SettingsThree', 
        nav: true 
       } 
      ]).buildNavigationModel(); 

    function getSelectedObj() { 
     return selectedObj; 
    } 

    return { 
     router: configRouter, 

     obj: selectedObj, // privileged property which is accessed by other modules via the getSelectedObj method, this prop gets set in the activate function depending on the param 
     getSelectedObj: getSelectedObj, // method which returns the current selected obj 

     activate: function (objId) { 

      if (objId == 'New') { 

       // create a new object with default props 

      } else { 

       // retrieve the data for the selected obj from API via the 'objId' param 

      } 

     } 
    } 
}); 



// SettingsOne module - child route module 

define(['viewmodels/parentRouter'], function(parentRouter) { 

    // this module simply gets a property from the parent routers module and binds it to form inputs in its View (which update automatically) so the user can edit information on that obj 


    var obj = parentRouter.getSelectedObj(); // get the current selected obj via parent routers module method 

    return { 
     obj: obj 
    } 
}); 


Below is the shell module of my app, showing the main application router. 
// Shell.js 
define([ 
    'plugins/router' 
], function (router) { 
    var routes = [ 
      { 
       route: '', 
       moduleId: 'viewmodels/home' 
      }, 
      { 
       route: ':id*configs', 
       moduleId: 'viewmodels/parentRouter' 
      } 
     ]; 

    return { 
     router: router, 
     activate: function() { 
      return router.map(routes) 
        .mapUnknownRoutes('viewmodels/notfound', 'not-found') 
        .activate(); 
     } 
    } 
}); 

回答

0

我不认为有什么不妥激活孩子之前每次激活父。如果你不想retreval再次发生,使其有条件的,例如:

define(function (require) { 
    var 
     $ = require('jquery'), 
     Q = require('q'), 

     activate = function() { 
      return load(); 
     }, 

     loadPromise = null, 

     load = function() { 
      return loadPromise || (loadPromise = Q($.get('/my/api')) 
        .then(function (data) { 
         //use data; 
        })); 
     }; 

     return { 
      activate: activate 
     } 
}); 
+0

非常感谢。这基本上是我目前正在做的。只是不觉得这是由杜兰德设计? –

0

我面临着类似的问题,我不希望我的父母VM有激活再次调用就可以了。从迪朗达尔Doc的这听起来像这应该得到支持:

From Module Reuse heading here

如果模块有一个与之关联的子路由器。该实例将被保留。

这就是说我没有能够得到这个工作我自己,但我认为它走向你的问题。看起来Durandal确实试图支持这个功能,但是我们都遗漏了一些细微差别。如果我知道了,我会在这里更新。

+0

那太棒了!谢谢。 –

相关问题