如何使用AngularJS重新加载或重新渲染整个页面

310

在根据多个用户上下文呈现整个页面并发出多个$http请求后,我希望用户能够切换上下文并重新呈现所有内容(重新发送所有$http请求等)。如果我只是将用户重定向到其他地方,事情会正常工作:

$scope.on_impersonate_success = function(response) {
  //$window.location.reload(); // This cancels any current request
  $location.path('/'); // This works as expected, if path != current_path
};

$scope.impersonate = function(username) {
  return auth.impersonate(username)
    .then($scope.on_impersonate_success, $scope.on_auth_failed);
};

如果我使用$window.location.reload(),那么等待响应的一些$http请求在auth.impersonate(username)被取消,所以我不能使用它。此外,黑客方法$location.path($location.path())也无法工作(没有任何反应)。

有没有其他方法可以重新渲染页面而不需要手动重新发出所有请求?


正如Alvaro Joao在下面所说,您需要使用angular-route.js才能使其正常工作。http://www.bennadel.com/blog/2770-route-must-be-injected-in-order-to-enable-the-routechangesuccess-event-in-angularjs.htm - Yvonne Aburrow
可能是AngularJs:重新加载页面的重复问题。 - Alena Kastsiukavets
13个回答

409

记录一下,如果要强制Angular重新渲染当前页面,您可以使用:

$route.reload();

根据AngularJS 文档

即使$location没有改变,也会导致$route服务重新加载当前路由。

由此,ngView会创建新的作用域并重新实例化控制器。


6
谢谢您的评论。由于某种原因,当我使用$route.reload()和正常刷新时,似乎会出现稍微不同的行为。例如,在刷新页面时,一个选项卡被设置为最初显示,但是当使用reload方法时,似乎重新加载页面时未设置选项卡,不确定问题出在哪里。 - Doug Molineux
2
这个是否也运行了过滤器/服务?出现了不想要的持久状态。编辑:尽管回答了问题并且这很有帮助,但还是点了赞。谢谢。 - grant
11
请确保将$route注入到控制器中,以使其正常工作。 - Neel
6
ngRoute模块已不再是核心的angular.js文件的一部分。如果你仍在使用$routeProvider,那么现在需要在HTML中包含angular-route.js文件。 - Alvaro Silvino
3
如果您使用stateProvider,可以使用$state.reload()来重新加载页面。 - Lalit Rao
显示剩余5条评论

321

$route.reload()方法会重新初始化控制器,但不会重置服务。如果您想重置整个应用程序状态,可以使用以下方法:

$window.location.reload();

这是一个标准DOM方法,您可以通过注入$window服务来访问它。
如果您想确保从服务器重新加载页面,例如当您使用Django或另一个Web框架并且您需要进行新的服务器端呈现时,请将true作为参数传递给reload,如文档中所述。由于这需要与服务器交互,因此速度会较慢,只有在必要时才执行。

Angular 2

以上内容适用于Angular 1。我没有使用Angular 2,那里的服务似乎不同,有RouterLocationDOCUMENT。我没有测试过不同的行为。

2
值得注意的是,我们不应该在服务中存储状态,这样才不会需要“重启”服务。 - andersonvom
20
谁说的?缓存数据应该存储在哪里? - danza
6
由于数据存储在服务中而非无状态,因此我遇到了许多错误。除非涉及缓存服务(在这种情况下,会有一个接口将其清除),否则我会将数据保留在控制器中而非服务中。例如,可以将数据保留在本地存储中,并使用服务来访问它。这将使服务不必直接保留数据。 - andersonvom
2
@danza 缓存数据应该存储在哪里? ... 模型对象中?然而,Angular在命名其MVCS组件方面做得很糟糕。我通过module.value API注入可注入的模型对象。然后,我在ng服务上定义了各种API,这些API修改模型对象的工作更像是命令。 - jusopi
2
可以这样做,但这不是良好的实践。请参考$window的文档,使用它的原因在开头已经解释了:“虽然在JavaScript中,window是全局可用的,但会造成可测试性问题,因为它是一个全局变量。在Angular中,我们总是通过$window服务来引用它,这样它就可以被覆盖、移除或模拟进行测试”。 - danza
显示剩余10条评论

39
重新加载给定路由路径的页面的方法是:

$location.path('/path1/path2');
$route.reload();

6
不知道为什么,但是.reload()方法似乎在这里不起作用。它没有重新加载任何东西。 - mircobabini

29

如果你正在使用angular ui-router,这将是最佳解决方案。

$scope.myLoadingFunction = function() {
    $state.reload();
};

在我的 CLI 项目部署到共享主机后,当我重新加载项目时,它会出现 404 错误。为了解决这个问题,我使用了 'use hash'。如果我添加了 'use hash',那么它就可以使用 '#' 运行,但我不想要这个,有没有什么方法可以解决这个问题。 - T. Shashwat

24

也许您在声明控制器的依赖项时忘记添加 "$route":

app.controller('NameCtrl', ['$scope','$route', function($scope,$route) {   
   // $route.reload(); Then this should work fine.
}]);

9

使用angularjs重新加载所有内容,可以使用window.location.reload()方法。

请查看可工作的示例

HTML

<div ng-controller="MyCtrl">  
<button  ng-click="reloadPage();">Reset</button>
</div>

angularJS

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

function MyCtrl($scope) {
    $scope.reloadPage = function(){window.location.reload();}
}

http://jsfiddle.net/HB7LU/22324/


7

如果您想在刷新使用的任何服务时刷新控制器,可以使用以下解决方案:

  • 注入 $state

例如:

app.controller('myCtrl',['$scope','MyService','$state', function($scope,MyService,$state) {

    //At the point where you want to refresh the controller including MyServices

    $state.reload();

    //OR:

    $state.go($state.current, {}, {reload: true});
}

这将刷新控制器和HTML,你可以称之为“刷新”或“重新渲染”。

2
这是针对UI Router而不是Angular的。 - dgzornoza

7

请尝试以下方法之一:

$route.reload(); // don't forget to inject $route in your controller
$window.location.reload();
location.reload();

6

在 Angular 2 之前(AngularJs)

通过路由(route)

$route.reload();

如果您想重新加载整个应用程序

$window.location.reload();

Angular 2+

import { Location } from '@angular/common';

constructor(private location: Location) {}

ngOnInit() {  }

load() {
    this.location.reload()
}

或者

constructor(private location: Location) {}

ngOnInit() {  }

Methods (){
    this.ngOnInit();
}

FYI - Angular 7:「属性 'reload' 在类型 'Location' 上不存在。」 - ACEG
@Cristina,感谢你的信息。我在使用 Angular 7 之前就用过这个了。 - Thilina Sampath

5

我认为最简单的解决方案是,在想要在返回时重新加载的路由中添加'/'。

例如:

不要使用以下方式:

$routeProvider
  .when('/About', {
    templateUrl: 'about.html',
    controller: 'AboutCtrl'
  })

使用,

$routeProvider
  .when('/About/', { //notice the '/' at the end 
    templateUrl: 'about.html',
    controller: 'AboutCtrl'
  })

2
@PardeepJain 这对我有用。这就是为什么这是一个答案。你给我的回答投了反对票吗? - diyoda_
1
不,根本不需要点踩你的回答。太神奇了,不知道为什么同样的代码在我的Angular2中不能运行。 - Pardeep Jain
2
完美的解决方案。谢谢! - simon
这个方法即使你的原始路径是应用程序的根目录 - / 也可以正常工作 :O 现在我的路由看起来像这样:// - MadPhysicist
在Angular 6中,使用#后它可以工作,同样也适用于Angular2。我认为是这样的。 - T. Shashwat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接