2014-12-29 90 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

那太棒了!謝謝。 –

相關問題