2014-06-11 722 views
14

嘿,我遇到了我認爲是常見的路由問題,但我無法找出解決方案。基本上我的頁面有兩種狀態,基本和高級,我希望兩種狀態的URL模式相同,但是隻加載當前狀態的模板(從控制器內部過渡到此模板)AngularUI路由器:具有相同url模式的多個狀態

config(function ($stateProvider) { 

    $stateProvider.state('basic', { 
    url: '/:post', 
    templateUrl: function (stateParams) { 
     return 'post-' + stateParams.post + '-tmpl.html'; 
    } 
    }); 

    $stateProvider.state('advanced', { 
    url: '/:post', 
    templateUrl: function (stateParams) { 
     return 'post-' + stateParams.post + '-advanced-tmpl.html'; 
    } 
    }); 
}) 

controller('myCtrl', function ($state) { 
    // 
    // In this case, I would expect only the template from 
    // the advanced state to load, but both templates are trying 
    // to load. 
    $state.transitionTo('advanced', {post: 2}); 
} 

我假設導航到匹配的模式加載給定的狀態,這就是爲什麼當它匹配時,兩個模板試圖加載。有什麼方法可以完成相同的網址模式,但只有基於當前狀態的不同模板?

+0

我遇到同樣的問題。我認爲UI路由器基於狀態,而不是URL,但是這證明了相反的 –

+0

你找到了解決方案嗎? –

+0

我注意到,在第二次使用ui-sref實現的此配置(您的高級)中單擊第二個狀態時,會加載正確的模板。 (瀏覽器地址欄更新,因爲它應該是第一次) –

回答

17

假設你不能有兩個國家使用相同的URL,你爲什麼不走和兩個狀態合併成一個? Ui路由器已經允許你有一個自定義函數來返回模板。你只需要添加一個隱藏的自定義參數(讓我們將他advanced調用)的狀態聲明:

$stateProvider.state('basicOrAdvanced', { 
    url: '/:post', 
    templateUrl: function (stateParams) { 
    if (stateParams.advanced) { 
     return 'post-' + stateParams.post + '-advanced-tmpl.html'; 
    } else { 
     return 'post-' + stateParams.post + '-tmpl.html'; 
    } 
    }, 
    params: { 
    advanced: False 
    } 
}); 

然後你把它叫做:

$state.transitionTo('basicOrAdvanced', {post: 2, advanced: True}) 

對於另一種可能的解決方案嵌套狀態和通用控制器,請參閱ui-router的github頁面上的問題#217#1096

的解決方案提出有創建第三狀態,其控制器做調度工作,而要在(basicadvanced)降落在兩個州都有空網址:如果

$stateProvider.state('basicOrAdvanced', { 
    url: '/:post', 
    controller: function($state, $stateParams) { 
    if($stateParams.advanced) { 
     $state.go('advanced', {post: $stateParams.post}); 
    } else { 
     $state.go('basic', {post: $stateParams.post}); 
    } 
    }, 
    params: { 
    advanced: False 
    } 
} 

該解決方案是更好的狀態在多個方面不同比簡單templateUrl(例如,如果它們具有完全獨立的控制器等)


另見another question on StackOverflow about a similar issue

+0

這也適用於ui-sref嗎?我明白你的意思,提供解決方案,但我想避免你的方法。如果它不僅與其關聯的模板可能發生變化,還會與ui-router狀態相關的數據或其他屬性呢? –

+0

例如,我有一個用例,其中「:post」是多語言上下文中的動態值。所以我想要一個名字爲'about'和url':page'的國家能夠擁有一個url/about-english和/ about-dutch。還有其他類似的狀態有不同的數據屬性(和其他)綁定到這些特定的狀態 –

+0

它應該與ui-sref一起工作,是的。 – DzinX

-1

您需要使用嵌套的狀態

config(function ($stateProvider) { 


    $stateProvider.state('post', { 
    url: '/:post', 
    templateUrl: function (stateParams) { 
     return 'post-' + stateParams.post + '-advanced-tmpl.html'; 
    } 
    }); 

    $stateProvider.state('post.basic', { 
    url: '/:post', 
    templateUrl: function (stateParams) { 
     return 'post-' + stateParams.post + '-tmpl.html'; 
    } 
    }); 

}) 

controller('myCtrl', function ($state, $timeout) { 
    // go to advanced 
    $state.transitionTo('post', {post: 2}); 
    // after 500ms switch to basic 
    $timeout(function() { 
     $state.transitionTo('post.basic', {post: 2}); 
    }, 500) 
} 
+0

謝謝,但是當我做這個改變時,我在控制檯中得到了「Uncaught object」。 – ThinkingInBits

+0

@ThinkingInBits更新的答案,我基本上從你複製它,你的參數名稱在uri和你實際傳遞的應該匹配。 – vittore

+0

哎呀,那只是一個錯字。他們在我的代碼中匹配。 – ThinkingInBits

1

這是AngularJS非常有用,

您可以指定動態路由與相同的URL模式多狀態

我的代碼遵循能對您有用,

Module Intialization,

var app = angular.module("koops_app", ['ui.router','ui.bootstrap']); //here you have to define all your required module for your project that you should inject... 

此外,

app.config(function ($locationProvider, $httpProvider, $stateProvider, $urlRouterProvider, $wampProvider) { 


    // When No Routing i.e Default Routing 
    $urlRouterProvider.when('', '/dashboard'); 


    // 404 
    $stateProvider.state("404", { 
     url: "/404", 
     templateUrl: 'template/404.html', 
    }); 


    // When Only One Argument i.e. Only Module Name 
    $stateProvider.state("default", { 
     url: "/:section", 
     templateUrl: 'views/View-to-be-load.html', //can use $stateParams.section for dynamic 
     reload: true, 
     resolve: { 
      loadController: ['$q', '$stateParams', '$state', 
         function ($q, $stateParams, $state) { 
          var deferred = $q.defer(); 
          deferred.resolve(); 
          return deferred.promise; 
         } 
        ] 
     }, 
     controllerProvider: function ($stateParams) { 
      return 'controllerName'; 
     } 
    }); 



     // When Two Argument i.e. Module/Controller 
     $stateProvider.state("default/title", { 
      url: "/:section/:title", 
      templateUrl: 'views/View-to-be-load.html', //can use $stateParams.section for dynamic 
      reload: true, 
      resolve: { 
       loadController: ['$q', '$stateParams', '$state', 
          function ($q, $stateParams, $state) { 
           var deferred = $q.defer(); 
           deferred.resolve(); 
           return deferred.promise; 
          } 
         ] 
      }, 
      controllerProvider: function ($stateParams) { 
       return 'controllerName'; 
      } 
     }); 



     // When Three Arguments i.e. Module/Controller/id 
     $stateProvider.state("default/title/id", { 
      url: "/:section/:title/:id", 
      templateUrl: 'views/View-to-be-load.html', //can use $stateParams.section for dynamic 
      reload: true, 
      resolve: { 
       loadController: ['$q', '$stateParams', '$state', 
          function ($q, $stateParams, $state) { 
           var deferred = $q.defer(); 
           deferred.resolve(); 
           return deferred.promise; 
          } 
         ] 
      }, 
      controllerProvider: function ($stateParams) { 
       return 'controllerName'; 
      } 
    }); 



     // Otherwise 
     $urlRouterProvider.otherwise("/404"); 

可能這是對你有幫助... 享受...

+0

這不回答問題。你的URL模式與每個狀態定義不同。我的用例是,如果你在多個狀態下使用「/:section」作爲你的url模式。 – ThinkingInBits

+0

我可以看到你的答案在兩個或多個不同的$ stateProvider.state()條目下使用相同的URL嗎? –

+0

是的,它使用相同的url在不同的狀態,但具有相同的patern @CodeUniqueelyly –

-1

爲什麼你會希望有映射到相同的URL兩種不同的觀點。當用戶想要在其中一個州添加書籤時,您是否想到了這個問題?那麼如果他們具有完全相同的網址,您怎麼知道哪一個是?

我建議定義就像兩個不同的狀態:

  • /:後 - 很簡單視圖
  • /:交/高級 - 針對高級視圖

這是可以做到將/:post定義爲抽象狀態和簡單和高級視圖的兩種不同狀態。爲了方便,簡單的視圖將作爲默認值。如果您喜歡這個創意,我可以爲您提供一個示例解決方案。

另一種選擇是添加URL參數,例如:

  • /:後 - 很簡單視圖
  • /:後視=先進

我希望這個?答案會幫助你。至少從不同的角度看待事物;)。

+0

它是關於一個url模式,而不是一個url –

+0

謝謝你的洞察力。我們對這些路由名稱有特定的要求和邏輯。用戶不能簡單地爲這些URL之一添加書籤......事實上,如果他們試圖通過地址欄直接導航到這裏,它們將被重定向到一個單獨的視圖/控制器。然而,我當時確實需要能夠區分相同URL模式的控制器和視圖。 – ThinkingInBits

相關問題