在 Angular 中更改路线会导致重新评估先前路线控制器上的功能
Changing route in Angular causes re-evaluation of functions on the previous route's controller
我有一条路线(例如 /items
),它的控制器有
$scope.pathForItem = function (item) {...}
方法,在模板中用于显示列表中每个项目的路径。当我在此页面上并单击任何 link 以更改路线时,Angular 会在其代码中的某处调用 $rootScope.$apply()
,这会导致重新评估 [=] 上定义的某些函数14=]。问题在于,这也会重新评估先前路由控制器范围内的功能,因此会为页面上的每个项目再次调用 pathForItem
一次。通常这不是什么大问题 - 这是不必要的,但不会导致任何错误。
但是,当我尝试注销时它会导致错误。 pathForItem
假设 user
对象存在(它从 authService
获得)并且它通常有效,因为我们确保用户存在于此路由的 resolve
函数中。现在,当有人尝试注销时,Angular 调用 $rootScope.$apply()
并再次尝试为所有项目调用 pathForItem
。然而,在中间的某个地方,用户最终被删除,authService.currentUser()
开始返回 null
并且所有对 pathForItem
的进一步调用都会引发错误...
真的应该这样吗? Angular 的 $rootScope.$apply
是否也应该为之前路由的控制器调用函数?是否有一些通用的解决方法,或者我是否必须确保所有控制器中的所有函数也在模板中使用,始终检查它们使用的所有对象是否确实存在,即使我已经在 resolve
中检查过了功能?
我正在使用 Angular 1.3.10 和 ngRoute。
(插值-)表达式中的函数在每个摘要循环中都会被调用,您不可能提前知道这将在何时发生。因此,您的函数必须做好准备,不仅要比您预期的更频繁地被调用,而且还要在意想不到的时候被调用。
你的问题的罪魁祸首是 html5 模式。有一个重写链接和调用的全局事件处理程序 $apply
。问题是即使未启用 html5 模式,它也会完成。我认为这是一个错误,因为文档说
When html5Mode is enabled, enables/disables url rewriting for relative links
无论如何,您可以在配置块中关闭此行为:
$locationProvider.html5Mode({rewriteLinks: false});
有关详细信息,请参阅 docs。如果你需要这种行为,那么你要么为你的情况准备你的函数,要么让 $scope.pathForItem
成为一个值。反正我推荐后一种。
我有一条路线(例如 /items
),它的控制器有
$scope.pathForItem = function (item) {...}
方法,在模板中用于显示列表中每个项目的路径。当我在此页面上并单击任何 link 以更改路线时,Angular 会在其代码中的某处调用 $rootScope.$apply()
,这会导致重新评估 [=] 上定义的某些函数14=]。问题在于,这也会重新评估先前路由控制器范围内的功能,因此会为页面上的每个项目再次调用 pathForItem
一次。通常这不是什么大问题 - 这是不必要的,但不会导致任何错误。
但是,当我尝试注销时它会导致错误。 pathForItem
假设 user
对象存在(它从 authService
获得)并且它通常有效,因为我们确保用户存在于此路由的 resolve
函数中。现在,当有人尝试注销时,Angular 调用 $rootScope.$apply()
并再次尝试为所有项目调用 pathForItem
。然而,在中间的某个地方,用户最终被删除,authService.currentUser()
开始返回 null
并且所有对 pathForItem
的进一步调用都会引发错误...
真的应该这样吗? Angular 的 $rootScope.$apply
是否也应该为之前路由的控制器调用函数?是否有一些通用的解决方法,或者我是否必须确保所有控制器中的所有函数也在模板中使用,始终检查它们使用的所有对象是否确实存在,即使我已经在 resolve
中检查过了功能?
我正在使用 Angular 1.3.10 和 ngRoute。
(插值-)表达式中的函数在每个摘要循环中都会被调用,您不可能提前知道这将在何时发生。因此,您的函数必须做好准备,不仅要比您预期的更频繁地被调用,而且还要在意想不到的时候被调用。
你的问题的罪魁祸首是 html5 模式。有一个重写链接和调用的全局事件处理程序 $apply
。问题是即使未启用 html5 模式,它也会完成。我认为这是一个错误,因为文档说
When html5Mode is enabled, enables/disables url rewriting for relative links
无论如何,您可以在配置块中关闭此行为:
$locationProvider.html5Mode({rewriteLinks: false});
有关详细信息,请参阅 docs。如果你需要这种行为,那么你要么为你的情况准备你的函数,要么让 $scope.pathForItem
成为一个值。反正我推荐后一种。