在使用Ionic框架登录/注销时清除历史记录并重新加载页面

80

我是初学Ionic移动应用开发者。在登录和退出时,我需要重新加载页面以刷新数据,然而$state.go('mainPage')会带用户回到视图但不重新加载页面——其后面的控制器从未被调用。

在Ionic中有没有一种清除历史记录并重新加载状态的方法?

14个回答

124

欢迎使用该框架!实际上,Ionic中的路由是由ui-router提供支持的。您可能需要查看这个之前的SO问题,以找到几种不同的方法来完成此操作。

如果您只想重新加载状态,则可以使用:

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

如果您真的想重新加载页面(即您希望重新引导一切),那么您可以使用:

$window.location.reload(true)

祝你好运!


13
这个解决方案对我不起作用。$state.go($state.current, {}, {reload: true}); - hackp0int
@IamStalker,你能否提供更多信息或者一个CodePen/Fiddle/Plunk作为示例? - JimTheDev
9
如果在状态定义中使用了默认的cache:true,则$state.go($state.current, {}, {reload: true});无法正常工作。此问题已经在#ionic 1.0.0-RC2和1.0.0版本中测试过。请查看我的答案。 - ABCD.ca
使用'$state.go($state.current, {}, {reload: true});'可以刷新视图,但是侧边菜单和标题会消失! - Afflatus
对我来说,第一个答案陷入了循环,而第二个则抛出了错误。 - alphapilgrim
显示剩余3条评论

25
我发现JimTheDev的答案只在状态定义中设置了cache:false时起作用。如果视图被缓存,您可以使用$ionicHistory.clearCache(),然后使用$state.go('app.fooDestinationView')从一个状态导航到缓存但需要刷新的状态。
请参见我的答案,因为它需要对Ionic进行简单更改,并且我创建了一个拉取请求: https://dev59.com/Ul4b5IYBdhLWcg3wzUYp#30224972

1
好东西。我实际上并没有在我的ionic应用中使用它,所以我很感激你跟进缓存功能。看起来你的PR将会被合并到1.0.1版本中。一旦发布,我会在我的原始帖子中注明你的贡献,并鼓励人们去尝试一下。 - JimTheDev

18

我已经找到了一个解决方案,帮助我完成了它。在ion-view标签上设置cache-view="false"解决了我的问题。

<ion-view cache-view="false" view-title="My Title!">
  ....
</ion-view>

禁用缓存视图会导致性能显著下降,您应该避免使用此选项。相反,您可以处理ionicView事件。请参见:https://dev59.com/U18e5IYBdhLWcg3w7-Nz#33708463 - ezain
@ezain,你能告诉我性能会受到什么影响吗? - Rajeshwar
@Rajeshwar,当启用缓存系统时,Ionic 会将视图生成的所有 DOM 隐藏起来,当视图变化发生时,您无需重新计算 DOM。如果您的 DOM 很重并且需要在所有转换更改中生成它,您可能会在转换动画中遇到延迟问题。如果仅禁用缓存的原因是重新加载控制器,请使用 ionicView 事件。 - ezain
@ezain,有很多方法可以实现禁用缓存的功能。我几乎尝试了所有的方法,但都没有成功。而这个方法给了我我需要的结果。即使页面有点大,我也没有看到任何明显的加载延迟。因此,我更喜欢这种方式而不是其他方式。 - Rajeshwar

18

正确答案:

$window.location.reload(true);

1
这个答案被标记为质量较低。你能否尝试解释一下为什么它是正确的答案? - Jorge Leitao
1
因为它使用$window而不是window - EpokK
您所说的正确,如果您使用 .location.reload 语法,那么使用 $window 是有意义的。我已经更改了我的答案,以便我们对未来的读者保持一致。在某些情况下,$state.go 语法也可能会很有用。 - JimTheDev
只有这个答案对我有帮助,而不是被标记的那个。 - Michal
我曾经喜欢那种方法,但有些人报告说它会在某些设备上(Android 4.4,Chrome)导致无限循环重新加载。 - Oleg Cheremisin

11

重新加载页面并不是最好的方法。

你可以处理状态更改事件来重新加载数据而无需重新加载视图本身。

在这里阅读关于ionicView生命周期的内容:

http://blog.ionic.io/navigating-the-changes/

并在进入之前处理事件以重新加载数据。

$scope.$on('$ionicView.beforeEnter', function(){
  // Any thing you can think of
});

这似乎是最好的方法。 - markau
具体而言,您可以检查状态是否来自缓存,如果是,则调用一些 API 来刷新它:$scope.$on('$ionicView.beforeEnter', function(scopes, states) { if (states.fromCache) { ... } } - jakub.g
@jakub.g 如果您不想缓存一个视图,您可以禁用此特定视图的缓存,这更简单。 - ezain

6
在我的情况下,我只需要清除视图并重新启动控制器。我可以使用以下代码片段实现我的意图:
$ionicHistory.clearCache([$state.current.name]).then(function() {
  $state.reload();
});

缓存仍在工作,只是视图被清除了。 ionic --version 显示版本为1.7.5。

附注: 当状态具有参数时,您必须在视图/状态标识中定义它们。 请检查此 pastebin:http://pastebin.com/2CaGYpnz - glaucomorais
你的代码中有错误。 正确版本 $ionicHistory.clearCache([$state.current.name]).then(function() { $state.reload(); }); - Kirill A
只是缺少一个括号。 - user623396

1

以上提到的解决方案都无法适用于主机名与localhost不同的情况!

我不得不将notify: false添加到我传递给$state.go的选项列表中,以避免在调用$window.location.reload之前调用Angular变更监听器。最终代码如下:

$state.go('home', {}, {reload: true, notify: false});

>>> 编辑-根据您的浏览器,可能需要使用$timeout >>>

$timeout(function () { $window.location.reload(true); }, 100);

<<< 编辑结束 <<<

更多信息请参见ui-router reference


0

正如@ezain所指出的那样,只有在必要时才重新加载控制器。更新数据的另一种更清晰的方法是在更改状态时使用广播事件,并在需要在视图上更新数据的控制器中侦听此类事件。

例如:在您的登录/注销函数中,您可以这样做:

$scope.login = function(){
    //After login logic then send a broadcast
    $rootScope.$broadcast("user-logged-in");
    $state.go("mainPage");
};
$scope.logout = function(){
   //After logout logic then send a broadcast
   $rootScope.$broadcast("user-logged-out");
   $state.go("mainPage");
};

现在在你的mainPage控制器中,通过使用$on函数来监听mainPage控制器内部的广播,从而触发视图中的更改,就像这样:

$scope.$on("user-logged-in", function(){
     //update mainPage view data here eg. $scope.username = 'John';
});

$scope.$on("user-logged-out", function(){
    //update mainPage view data here eg. $scope.username = '';
});

0

我需要重新加载状态来使滚动条工作。当通过另一个状态-'注册'时,它们不起作用。如果在注册后强制关闭应用程序并再次打开,即直接进入“主页”状态,则滚动条将起作用。以上解决方案都无效。

当注册后,我替换了:

$state.go("home");

使用

window.location = "index.html"; 

应用程序已重新加载,滚动条正常工作。


0

我正在尝试使用AngularJS刷新页面,当我看到网站时感到困惑,但是没有代码可以工作,然后我找到了重新加载页面的解决方案。

$state.go('path',null,{reload:true});

在一个函数中使用这个,它会起作用。


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