如何在angular.js中实现history.back()


190

我有指令,它是带有后退按钮的网站标题,我想单击可返回上一页。我如何以有角度的方式做到这一点?

我努力了:

<header class="title">
<a class="back" ng-class="icons"><img src="../media/icons/right_circular.png" ng-click="history.back()" /></a>
<h1>{{title}}</h1>
<a href="/home" class="home" ng-class="icons"><img src="../media/icons/53-house.png" /></a>   
</header>

这是指令js:

myApp.directive('siteHeader', function () {
    return {
        restrict: 'E',
        templateUrl: 'partials/siteHeader.html',
        scope: {
            title: '@title',
            icons: '@icons'
        }
    };
});

但什么也没发生。我查看了有关$ location的angular.js API,但未找到有关后退按钮或的任何信息history.back()


1
您提到这对您有用。它会带您进入应用程序中的不同页面,还是只是浏览器返回?看来它确实将浏览器带回了我。
Chookoos 2013年

如果您已将AngularJS设置为使用HTML5模式,则转到浏览器历史记录中已存在的任何页面都将使用缓存的版本,而不重新加载它。我正在处理的项目使用的是旧代码和新代码的混合,用AngularJS保存数据后,上一页会更改。升级第一页以使用AngularJS并不是一种选择,因此我不得不加载非AngularJS的第三页以重定向回第一页。这不是一个很好的解决方案,但是可以。
CJ Dennis

Answers:


262

您需要在指令中使用链接函数:

link: function(scope, element, attrs) {
     element.on('click', function() {
         $window.history.back();
     });
 }

参见jsFiddle


但是我的标题中有2个按钮,如果我了解您的代码,则一个按钮用于返回主页,一个按钮用于返回。如果链接功能中的元素是在这种情况下被单击的元素,则history.back也将应用于主页按钮吗?(这不好)
baba-dev

我对示例进行了一些更改。现在有两个按钮(后退和前进)。现在使用jQuery,这意味着scope.click需要$ apply()。
asgoth

8
此代码不可测试,您应该真正使用“ $ window”对象而不是“ window”。
仲裁者2013年

IE8可以使用吗?我不相信它有历史
尼尔

5
@ Neil,Angular 自豪地不支持IE8。所以不行。
说唱时间

133

角度路线会监视浏览器的位置,因此只需window.history.back()单击一下即可使用。

HTML:

<div class="nav-header" ng-click="doTheBack()">Reverse!</div>

JS:

$scope.doTheBack = function() {
  window.history.back();
};

我通常在我的应用程序控制器上创建一个名为“ $ back”的全局函数,通常将其放在body标签上。

angular.module('myApp').controller('AppCtrl', ['$scope', function($scope) {
  $scope.$back = function() { 
    window.history.back();
  };
}]);

然后我可以在我的应用程序中的任何地方做 <a ng-click="$back()">Back</a>

(如果您希望它更具可测试性,请将$ window服务注入到控制器中并使用$window.history.back())。


9
我建议不要将任何内容放在“全局函数”中。全球状态可能会发生很多事情。在这种情况下,这主要是波动性。例如,来自第三方(或其他开发人员,如果您是一个大型团队)的代码,指令或服务可以轻松地修改$ scope。$ back作为其子级。这可能很难调试。将服务注入每个组件并在需要的地方公开功能绝对是更好的做法。该示例仅是“应用程序全局”的示例,但存在风险
Ben Lesh 2014年

资料来源:我遇到了一些东西,我被困在一个“全球”应用程序中$ scope咬我太多次了,我已经停止使用该技术来支持服务了。仍然可以加油,但是更容易解决。
Ben Lesh 2014年

65

理想情况下,使用简单的指令使控制器免受冗余$ window的影响

app.directive('back', ['$window', function($window) {
        return {
            restrict: 'A',
            link: function (scope, elem, attrs) {
                elem.bind('click', function () {
                    $window.history.back();
                });
            }
        };
    }]);

像这样使用:

<button back>Back</button>

很高兴您展示了$ window依赖性-这很重要。
克里斯·史密斯

20

另一个不错且可重用的解决方案是创建一个像这样的指令:

app.directive( 'backButton', function() {
    return {
        restrict: 'A',
        link: function( scope, element, attrs ) {
            element.on( 'click', function () {
                history.back();
                scope.$apply();
            } );
        }
    };
} );

然后像这样使用它:

<a href back-button>back</a>

1
重新排序结束的卷并重新命名指令和元素attr以使其相互匹配后,似乎可以使用。
remarsh 2014年

18

如果有用的话...我碰到了“达到10次$ digest()迭代。正在中止!” 使用$ window.history.back()时出错 IE9(当然,在其他浏览器中也可以)。

我通过使用它使其工作:

setTimeout(function() {
  $window.history.back();
},100);

其他答案则使用无格式window。您似乎正在使用$windowAngular服务。也许这是根本原因?
superjos 2013年

7
我在IE9下遇到了相同的错误,这解决了问题。参见github.com/angular/angular.js/issues/1417他对使用$ window是正确的,所有其他答案在这一点上都是“错误的”,请参阅docs.angularjs.org/api/ng.$window
tanguy_k

知道为什么100ms吗?那是一个相当长的延迟,它的工作量减少了吗?
凯文(Kevin)

@Kevin 100ms只是一个持续时间,我认为这是合理的,而且imo并不明显。实际上,较小的延迟可能会起作用。
Rob Bygrave 2014年

在我的应用中使用Angular默认导航时,我在最新的Chrome浏览器中遇到类似问题,并且延迟也无济于事。只有禁用Angular的导航管理才有帮助。
米2014年


1

发生语法错误。试试这个,它应该可以工作:

directives.directive('backButton', function(){
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function () {
                history.back();
                scope.$apply();
            });
        }
    }
});

1

角度4:

/* typescript */
import { Location } from '@angular/common';
// ...

@Component({
  // ...
})
export class MyComponent {

  constructor(private location: Location) { } 

  goBack() {
    this.location.back(); // go back to previous location
  }
}

0

对我来说,我的问题是我需要导航回去然后过渡到另一个状态。所以使用$window.history.back()是行不通的,因为由于某种原因,过渡发生在history.back()发生之前,所以我不得不将过渡包装在一个超时函数中,就像这样。

$window.history.back();
setTimeout(function() {
  $state.transitionTo("tab.jobs"); }, 100);

这解决了我的问题。


0

在AngularJS2中,我发现了一种新方法,也许是一样的东西,但是在这个新版本中:

import {Router, RouteConfig, ROUTER_DIRECTIVES, Location} from 'angular2/router'; 

(...)

constructor(private _router: Router, private _location: Location) {}

onSubmit() {
    (...)
    self._location.back();
}

完成我的功能后,我可以看到我的应用程序正在从angular2 / router转到上一页usgin位置。

https://angular.io/docs/ts/latest/api/common/index/Location-class.html


它有效,您必须从@ angular / common而不是@ angular / router导入它。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.