在Angular中更改路径会导致重新评估先前路径控制器上的功能

时间:2015-01-22 14:11:31

标签: javascript angularjs angularjs-scope ngroute

我有一条路线(例如/items)并且其控制器已经

$scope.pathForItem = function (item) {...}

方法,在模板中用于显示列表中每个项目的路径。当我在此页面上并单击任何链接以更改路径时,Angular会在其代码中的某处调用$rootScope.$apply(),这会导致重新评估$scope上定义的某些函数。问题是,这也会重新评估前一个路径控制器范围内的函数,从而为页面上的每个项目再次调用pathForItem一次。通常这不是一个大问题 - 这是不必要的,但不会导致任何错误。

但是,当我尝试退出时会导致错误。 pathForItem假设user对象存在(它来自authService)并且它通常有效,因为我们确保用户存在于此路由的resolve函数中。现在,当有人试图退出时,Angular会调用$rootScope.$apply()并尝试再次为所有项目调用pathForItem。但是,在中间的某个位置,用户最终被移除,authService.currentUser()开始返回null,所有进一步调用pathForItem都会引发错误...

真的应该这样吗? Angular的$rootScope.$apply呼叫是否也适用于前一路由的控制器?是否有一些通用的解决方法或者我必须确保所有控制器中也用于模板的所有函数,总是检查它们使用的所有对象是否实际存在,即使我已经在resolve中检查过它功能

我正在使用Angular 1.3.10和ngRoute。

1 个答案:

答案 0 :(得分:1)

在每个摘要周期中调用(插值 - )表达式中的函数,并且您可能事先知道何时会发生这种情况。因此,您的功能必须做好准备,不仅要比预期更频繁,还要在意外时间进行调用。

你的案子的罪魁祸首是html5模式。有一个全局事件处理程序可以重写链接和调用$apply。问题是,即使未启用html5模式,它也已完成。我认为这是一个错误,因为文档说

  

当html5Mode 启用时,启用/禁用相对链接的网址重写

无论如何,您可以在配置块中关闭此行为:

$locationProvider.html5Mode({rewriteLinks: false});

有关详细信息,请参阅docs。如果您需要此行为,则可以根据自己的情况准备函数,也可以使$scope.pathForItem成为值。无论如何我推荐后者。