2015-08-09 34 views
1

我正在使用angular和ng-route,并且想要处理简单的重定向,如果某些给定的解析返回false。但是,如果路由的模板包含ng-bind-html,则会出现一个“错误:[$ sce:unsafe]尝试在安全上下文中使用不安全的值。”即使没有理由在解析之前加载模板,也会触发错误。我发现的唯一的解决办法是从决心返回null(假不工作)...为什么路由器解决之前的角度分析模板已完成?

https://jsfiddle.net/pansay/wLkxkp5e/3/

.when('/abc/:id', { 
     template: 'should not get here <span ng-bind-html="ctrl.someData"></span>', // if :id was not found 
     controller: ['someData', function (someData) { 
       this.someData = someData; 
      }], 
      controllerAs: 'ctrl', 
     resolve: { 
      someData: ['$location', function ($location) { 
       // actual case: use the :id param to fetch data from some service 
       // but redirect if it returns false 
       $location.path('/abc'); 
       return false; 
      }] 
     } 
    }) 

但仍然意味着控制器/模板仍然解析,这似乎并不是所希望/记录的行为,并可能引发其他问题......这是否有充分的理由?

回答

1

当您从解析中返回false时,您实际上表示解析正常,返回值false被传递到范围。因此,它会在重定向之前进入该状态,其值为false。而且,由于someData与你看到的异常等

你需要做的是防止进入此状态下,如果你会做一个重定向一个奇怪的数据解析。要做到这一点,你需要回复一个承诺并拒绝它。

像这样:

someData: ['$location', '$q', function ($location, $q) { 
      return fetchFromSomeService.then(
       function(valueFromService) { 
        if(valueFromService === false) { 
        return $q.reject(); 
        } 
        return valueFromService; 
       } 
      }] 

对于您的代码示例,你可以简单地做到这一点,使其工作:

someData: ['$location', '$q', function ($location, $q) { 
       // actual case: use the :id param to fetch data from some service 
       // but redirect if it returns false 
       return $q.reject(); 
      }] 
+0

你是对的,它正常工作与承诺,我最终实现它如下所示: 'resolve:{'postsService','$ location',function(postsService,$ location){ return postsService.getPosts()。catch(function(){ $ location.path(appUrls .home); //如果帖子列表未找到,则重定向到主页 }); }] }' – pansay

+0

很高兴为你工作。你能将这个答案标记为答案吗?所以,人们会在搜索时看到这个问题的答案。他们很容易获得信息。 –

+0

我不知道为什么我的解决方案与.catch一起工作,但在另一个案例中没有。实际上,.catch错误处理程序的返回值仍然被传递给控制器​​,并且模板被解析。 因此,无论是成功处理程序还是错误处理程序,都必须返回被拒绝的承诺($ q.reject(),就像您的解决方案中一样),或者抛出错误。换句话说,无论是成功还是错误回调,链的最后一个处理程序的最后一个返回值都会被传递,除非该返回值是被拒绝的承诺,或者抛出了错误。 – pansay