Angular.js'de history.back () nasıl uygulanır?


191

Geri düğmeli site başlığı olan direktifim var ve bir önceki sayfaya geri dönmek için tıklayın. Açısal olarak nasıl yaparım?

Denedim:

<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>

ve bu js direktifi:

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

ama hiçbir şey olmadı. Angular.js API $ yer hakkında baktı ama geri düğmesi hakkında bir şey bulamadık veya history.back().


1
Bunun sizin için işe yaradığından bahsettiniz. Sizi uygulamanızdaki farklı sayfalara mı götürüyor yoksa tarayıcı geri mi dönüyor? Görünüşe göre tarayıcı bana geri dönüyor.
Chookoos

AngularJS'yi HTML5 modunu kullanacak şekilde ayarladıysanız, tarayıcının geçmişinde zaten bulunan herhangi bir sayfaya gitmek önbelleğe alınan sürümü kullanır ve yeniden yüklemez. Üzerinde çalıştığım proje eski ve yeni kodların bir karışımını kullanıyor ve veriler AngularJS ile kaydedildikten sonra bir önceki sayfa değişiyor. AngularJS'yi kullanmak için ilk sayfayı yükseltmek için bir seçenek değil, bu yüzden ilk sayfaya geri yönlendirmek için üçüncü, AngularJS olmayan bir sayfa yüklemem gerekti. Güzel bir çözüm değil, ama işe yarıyor.
CJ Dennis

Yanıtlar:


262

Direktifinizde bir link fonksiyonu kullanmanız gerekir:

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

Bkz. JsFiddle .


Ama eğer kodunuzu anlarsam, bağlantı fonksiyonundaki eleman bu durumda geçmişte tıklanan elemandır. (Bu iyi değil)? )
baba-dev

Örneği biraz değiştirdim. Şimdi iki düğme var (geri ve ileri). Şimdi jQuery kullanıyor, bu da kapsamda.
asgoth

8
Bu kod test edilemez, gerçekten 'pencere' yerine '$ pencere' nesnesini kullanmalısınız.
Hakem

Bu IE8 ile çalışır mı? Geçmişi olduğuna inanmıyorum
Neil

5
@Neil, Angular gururla IE8'i desteklemiyor. Yani, hayır.
Rap

133

Açısal yollar tarayıcının konumunu izler, bu nedenle basitçe bir window.history.back()şeyi tıkladığınızda kullanmak işe yarayacaktır.

HTML:

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

JS:

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

Uygulama denetleyicimde genellikle '$ back' adlı genel bir işlev oluştururum. Bu işlev genellikle gövde etiketine koyarım.

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

Sonra benim app herhangi bir yerde yapabilirim <a ng-click="$back()">Back</a>

(Daha test edilebilir olmasını istiyorsanız, $ window hizmetini kumandanıza enjekte edin ve kullanın $window.history.back()).


9
Ben bir şey "küresel işlevi" koymak karşı tavsiye ederim. Küresel devletin başına gelebilecek pek çok şey var . Bu durumda, çoğunlukla oynaklığıdır. Üçüncü bir taraftan (veya büyük bir ekipte bulunuyorsanız başka bir geliştiriciden) kod, bir yönerge veya bir hizmetin çocuk kapsamı için $ kapsamını kolayca değiştirebilir. Bu hata ayıklamak zor olabilir. Her bileşene bir servis enjekte etmek ve gerektiğinde işlevselliği ortaya çıkarmak kesinlikle daha iyi bir uygulamadır. Örnek sadece "uygulama için küresel", ancak risk var
Ben Lesh

Kaynak: Bir "global" uygulama $ kapsamı içinde sıkışmış şeyler saymak için beni çok kez ısırdı ve hizmetleri lehine bu tekniği kullanmayı bıraktım. Hangi hala sıkışmış olabilir, ama suss için çok daha kolay.
Ben Lesh

65

Denetleyicileri gereksiz $ penceresinden uzak tutmak için basit bir yönerge kullanın

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

Bunun gibi kullanın:

<button back>Back</button>

$ Pencere bağımlılığını gösterdiğinize sevindim - bu önemli.
Chris Smith

20

Bir başka güzel ve yeniden kullanılabilir bir çözüm gibi bir direktif yaratmaktır bu :

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

sonra sadece şu şekilde kullanın:

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

1
Kapatma kıvrımlarını yeniden sıraladığınızda ve yönerge ile element attr'ı birbiriyle eşleşecek şekilde yeniden adlandırdığınızda işe yarar.
remarsh

18

Yararlı olması durumunda ... "10 $ digest () yinelemelerine ulaşıldı. İptal ediliyor!" $ window.history.back () kullanılırken hata oluştu; IE9 ile (elbette diğer tarayıcılarda iyi çalışır).

Kullanarak işe aldım:

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

Diğer cevaplar ovadan yararlanır window. $windowAçısal hizmeti kullanıyor gibi görünüyorsunuz . Belki de temel sebep budur?
superjos

7
IE9 altında aynı hatayı aldım ve bu sorunu çözdü. Bkz. Github.com/angular/angular.js/issues/1417 $ penceresini kullanma konusunda haklı, diğer tüm cevaplar bu noktada "yanlış", bkz. Docs.angularjs.org/api/ng.$window
tanguy_k

Neden 100ms hakkında bir fikrin var mı? Bu oldukça gecikme, daha azıyla mı çalışıyor?
Kevin

@Kevin 100 ms sadece makul ve imo fark edilebilir olduğunu düşündüğüm bir süreydi. Gerçekten daha küçük bir gecikme işe yarayabilir.
Rob Bygrave

Uygulamamda Açısal varsayılan gezinme özelliğini kullanırken en son Chrome'da benzer sorunlar alıyorum ve gecikme de yardımcı olmayacak. Yalnızca Angular'ın gezinme yönetimini devre dışı bırakmak yardımcı oldu.
Domi

3

Veya sadece kod:

onClick="javascript:history.go(-1);"

Sevmek:

<a class="back" ng-class="icons">
   <img src="../media/icons/right_circular.png" onClick="javascript:history.go(-1);" />
</a>

1
bu pek çok düzeyde yanlış görünüyor, bkz. neredeyse 10 yıl önce bu blog yazısı
Rocco

1

Bir sözdizimi hatası oluştu. Bunu deneyin ve çalışması gerekir:

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

1

Açısal 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

Benim için sorunum, geriye dönüp başka bir duruma geçmem gerekti. Yani kullanarak$window.history.back() işe yaramadı çünkü bazı nedenlerden ötürü geçiş history.back () gerçekleşmeden önce gerçekleşti, bu yüzden geçişimi böyle bir zaman aşımı işlevine sarmak zorunda kaldım.

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

Bu benim sorunumu çözdü.


0

AngularJS2'de yeni bir yol buldum, belki de aynı şey ama bu yeni versiyonda:

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

(...)

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

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

İşlevimden sonra, uygulamamın angular2 / router'dan önceki sayfa usgin konumuna gittiğini görebiliyorum.

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


Çalışıyor, @ açısal / yönlendiriciden değil, @ açısal / ortaktan içe aktarmanız gerekiyor.
pleksus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.