【问题标题】:Optionally loading template in ngRoute可选地在 ngRoute 中加载模板
【发布时间】:2016-07-14 04:02:31
【问题描述】:

我有两个模板,分别是 a.htmlb.html。现在a.html 用于登录用户,b.html 用于未登录用户。身份验证是通过在单独的子域上运行的 api 进行的。现在我有一个电话告诉一个人是否在范围内进行了身份验证。

我怎样才能有选择地加载基于此的模板。一种方法是我加载b.html 并有条件地重定向经过身份验证的用户,但这不是我想要的。 这是我的 ngRoute 代码

var app = angular.module('app',['ngRoute']);

app.config(function ($routeProvider,$locationProvider) {
    $locationProvider.html5Mode(true);
    $routeProvider
    .when('/',{
            templateUrl : '/templates/b.html',
            controller  : 'mainController'
        })
    .otherwise({
        templateUrl : 'templates/404.html',
        controller  : 'mainController'
    });
});

app.controller('mainController', function($scope) {

});

【问题讨论】:

  • 条件路由是否适用?或者你是否有必要这两个模板必须共享相同的路径(浏览器地址栏中的相同 url)?
  • 网址必须相同。两者都在“/”上。我没有明白你所说的条件路由的意思。仅供参考,角度应用程序是 jekyll,所以那里没有变化。子域上的 Api 是 django
  • 好吧,如果我理解你的话,你要求你不想先加载b.html 然后重定向,但你是通过 api 进行身份验证。这是否意味着您希望以某种方式阻止您的 Angular 应用程序显示或更改路线,直到身份验证完成?
  • @MMhunter 是的。它将令牌发送到服务器并获取用户的状态。如果他通过了身份验证,则 a.html 否则为 b.html :)

标签: angularjs ngroute


【解决方案1】:

以下代码可以以某种方式满足您的要求,但实际上有点棘手,因为我使用 ng-include 而不是直接设置 templateUrl。

关键是使用resolve param in $routeProvider。当你传递一个 $promise 作为其中的成员时,路由器将等待它们全部被解析。

 app.controller('MainController', ['$scope','loadedTemplate',function ($scope,loadedTemplate) {
     //inject the template from the resolve function
     $scope.loadedTemplate = loadedTemplate;
 }]);

//Service to keep loginStatus
app.factory("loginService",function(){
    return {
      isLogin:false,
      loginStatusFetched:false,
  }
})

app.config(['$routeProvider',function ($routeProvider) {

    $routeProvider.
    when('/', {
        template: "<div ng-include='loadedTemplate'></div>",
        controller: 'MainController',
        resolve:{
          loadedTemplate:function($q, $http,$route,loginService) {
              console.log("fetching login status");
              if(loginService.loginStatusFeteched){
                    if(loginService.isLogin){
                          return "a.html"
                    }
                    else{
                            return "b.html"
                    }
              }
              console.log("fetching remote authentication");
              var deferred = $q.defer();
              $http({method: 'GET', url: 'http://jsonplaceholder.typicode.com/posts/1'})
                  .success(function(data) {

                      //update the login status here
                      loginService.loginStatusFeteched = true;
                      loginService.isLogin = true;
                      if(loginService.isLogin){
                        deferred.resolve("a.html");
                      }
                      else{
                        deferred.resolve("b.html");
                      }
                  })
                  .error(function(data){
                  //error
                      deferred.resolve("b.html");
                  });

              return deferred.promise;  
          }
        }
    })
}]);

我试图通过将templateUrl设置为一个函数来实现你所需要的,但它只需要routeParams,当resolve中的$promise被解析时,这个函数已经执行了,无法更改当前加载的模板。

您还可以尝试其他选择。您可以使用angular-ui-router 而不是ng-route 来处理状态更改,您可以在其中设置子状态并有条件地使用相同的url。

但我相信可能有更好的方法来实现您想要的。如果有人有更好的解决方案,请告诉我。

【讨论】:

    猜你喜欢
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多