2017-07-27 12 views
5

注意を使用し、バックボタン壊す:私は、スタンドアローンの実装別の既存のウェブサイトにアプリをAngularJSいるAngularJSアプリが別のウェブサイト内の単一ページのアプリケーションのために

AngularJSのV1.6.0を使用していますが、それが存在しますサイトの1つのページに表示され、残りのサイトにはAngularコードが実行されていません。

たとえば、サイト上の通常のページがで次のようになります。

http://example.com/any-page

その後、ユーザーがリンクをクリックすることができ、それは角度JSはそれで実行されているとのページにそれらを取る:

http://example.com/angularjs-app

このURLに着陸すると、それはAngularJSアプリをロードし、期待通りにURLに#!/を追加します。ヘッダーなどの残りの要素は含まれていないため、ユーザーにとってはまったく異なるセクションのように見えます。しかし、それはまた、戻るボタンを壊す。戻るボタンはhttp://example.com/any-pageに戻ることはできません。あなたが戻ってくるたびにAngularJSアプリのランディングビューが再度ロードされるだけです。つまり、AngularJSアプリページにはユーザーがいなくなり、/any-pageに戻ることはできません。

これはAngularJSルーティングと関係があると思います。これは、戻るときにURLの#!/部分を更新してアプリの最初のビューをリロードするように見えるためです。しかし私は間違っている可能性があります。

AngularJSアプリでは、さまざまなルートを訪れたときに戻るボタンが正常に機能することに注意してください。たとえば、#!/login#!/view-detailsなど、アプリ内のさまざまなルート/ビュー間を移動すると、いつでも戻るボタンからこれらのビューに戻ることができます。しかし、最初のビューに到達すると、動作を停止します。

これを回避する方法を知っている人はいますか?

注:私はこれについて様々な他のスタックオーバーフローの投稿を見てきましたが、バックボタンがまったく動作しないと考えられているようです。アプリではなく、元の非AngularJSページに戻ることはできません。

ルーティング設定

(function() { 
    "use strict"; 

    var routes = { 
     error: "/error", 
     forgottenPassword: "/forgotten-password", 
     home: "/home", 
     login: "/login", 
     orders: "/orders", 
     paymentDetails: "/payment-details", 
     personalDetails: "/personal-details", 
     subscriptions: "/subscriptions", 
     updatePassword: "/update-password", 
     accountVerification: "/account-verification", 
     register: '/register', 
     profile: '/profile', 
     accountConfirm: '/account-confirm', 
     deleteAccount: '/delete-account' 
    }; 

    var configFunc = function (
     $routeProvider, 
     $locationProvider, 
     CONFIG, 
     ROUTES) { 

     var resolve = { 
      isLoggedIn: [ 
       "$q", "ERRORS", "core.services.sessionsService", function ($q, ERRORS, sessionsService) { 
        return sessionsService.isLoggedIn().then(function (isLoggedIn) { 
         if (isLoggedIn) { 
          return isLoggedIn; 
         } 

         return $q.reject({ error: ERRORS.route.requiresAuth }); 
        }); 
       } 
      ] 
     }; 

     var getTemplateUrl = function(page) { 
      return CONFIG.rootPagesUrl + page; 
     }; 

     $routeProvider 
      .when("/", { 
       controller: "StartCtrl", 
       template: "" 
      }) 
      .when(ROUTES.login, { 
       templateUrl: getTemplateUrl("login.html"), 
       pageName: "Login" 
      }) 
      .when(ROUTES.forgottenPassword, { 
       templateUrl: getTemplateUrl("forgotten-password.html"), 
       pageName: "Forgotten Password" 
      }) 
      .when(ROUTES.home, { 
       templateUrl: getTemplateUrl("home.html"), 
       resolve: resolve 
      }) 
      .when(ROUTES.personalDetails, { 
       templateUrl: getTemplateUrl("personal-details.html"), 
       resolve: resolve 
      }) 
      .when(ROUTES.paymentDetails, { 
       templateUrl: getTemplateUrl("payment-details.html"), 
       resolve: resolve 
      }) 
      .when(ROUTES.orders, { 
       templateUrl: getTemplateUrl("orders.html"), 
       resolve: resolve 
      }) 
      .when(ROUTES.subscriptions, { 
       templateUrl: getTemplateUrl("subscriptions.html"), 
       resolve: resolve 
      }) 
      .when(ROUTES.updatePassword, { 
       templateUrl: getTemplateUrl("update-password.html"), 
       pageName: "Update Password" 
      }) 
      .when(ROUTES.accountVerification, { 
       templateUrl: getTemplateUrl("account-verification.html"), 
       pageName: "Account Verification" 
      }) 
      .when(ROUTES.error, { 
       templateUrl: getTemplateUrl("error.html"), 
       pageName: "Error" 
      }) 
      .when(ROUTES.register, { 
       templateUrl: getTemplateUrl("register.html"), 
       pageName: "Register" 
      }) 
      .when(ROUTES.profile, { 
       templateUrl: getTemplateUrl("profile.html"), 
       resolve: resolve, 
       pageName: "Profile" 
      }) 
      .when(ROUTES.accountConfirm, { 
       templateUrl: getTemplateUrl("accountConfirm.html"), 
       pageName: "Registration Complete" 
      }) 
      .when(ROUTES.deleteAccount, { 
       templateUrl: getTemplateUrl("deleteAccount.html"), 
       resolve: resolve, 
       pageName: "Delete Account" 
      }) 
      .otherwise({ 
       templateUrl: getTemplateUrl("login.html"), 
       pageName: "Login" 
      }); 
    }; 

    var config = [ 
     "$routeProvider", 
     "$locationProvider", 
     "CONFIG", 
     "ROUTES", 
     configFunc 
    ]; 

    var module = angular.module("app"); 
    module.constant("ROUTES", routes); 
    module.config(config); 
})(); 

NG-ビューが住んでいるインデックスの一部:

<body ng-app="app" ng-strict-di> 

    <div> 
     <div id="container" class="mpp-app"> 
      <div class="mpp-page" id="mpp-page"> 
       <div class="page-wrapper"> 
        <div class="ui-module-container"> 
         <div brand></div> 
        </div> 
        <div ng-view></div> 
       </div> 
      </div> 
      <div class="ui-module-container"> 
       <div footer></div> 
      </div> 
     </div> 
    </div> 

    <div id="spinner" class="hidden"><div class="icon"></div></div> 

StartCtrl

(function() { 
    "use strict"; 

    var func = function (
     $rootScope, 
     $scope, 
     $location, 
     ROUTES, 
     APP_EVENTS, 
     CORE_EVENTS, 
     SessionModel, 
     sessionsService, 
     configurationAggregator) { 

     var broadcast = function(event, args) { 
      $rootScope.$broadcast(event, args); 
     }; 

     var redirectToLogin = function() { 
      broadcast(APP_EVENTS.navigation.login); 
     }; 

     // check if user is signed in and has a valid session 
     var verifySession = function() { 
      sessionsService.verify().then(function() { 
       // if user is logged in navigate to profile 
       // otherwise navigate to login 
       configurationAggregator.getConfiguration().then(function() { 
        broadcast(APP_EVENTS.auth.login.success); 
        //broad cast(APP_EVENTS.navigation.home); 
        broadcast(APP_EVENTS.navigation.uktvProfile); 
       }, redirectToLogin); 
      }, redirectToLogin); 
     }; 

     // init 
     var sessionId = $location.search().guid; 

     if (angular.isDefined(sessionId) && sessionId !== null) { 
      broadcast(CORE_EVENTS.session.changed, { sessionId: sessionId }); 
      verifySession(); 
     } else { 
      verifySession(); 
     } 
    }; 

    var controller = [ 
     "$rootScope", 
     "$scope", 
     "$location", 
     "ROUTES", 
     "EVENTS", 
     "mpp.core.EVENTS", 
     "mpp.core.SessionModel", 
     "mpp.core.services.sessionsService", 
     "mpp.core.aggregators.configurationAggregator", 
     func 
    ]; 

    var module = angular.module("app"); 
    module.controller("StartCtrl", controller); 
})(); 
+0

外部URLへのルーティングには何を使用していますか? – Kamesh

+0

[AngularJS]の複製があります。戻るボタンで更新しないルートを使用しています(https://stackoverflow.com/questions/23457904/angularjs-using-routes-without-refreshes-on-back-button) –

+2

詳細はありますか? ?私は簡単なテストを作成し、すべてがその中で働いています。ルーティングの設定方法このシナリオで何が起こっているのかを理解するのに役立つデモです。 – Brian

答えて

2

AngularJSルータの問題ではありません(特定のバージョンのバグかもしれませんので、バージョンに関する情報を質問に追加してください)。しかし、ほとんどの場合、ルーターイベントハンドラにリダイレクトされている可能性があります(StartCtrl)。

チュートリアルでは、正常に動作しますAngularJSからたとえば、あなたはここでそれを得ることができます。

$routeProvider 
     .when('/', { 
      template: '<div>Hello</div>' 
     }) 
     .when(ROUTES.login, { 
      templateUrl: getTemplateUrl("login.html"), 
      pageName: "Login" 
     }) 
     .when(ROUTES.forgottenPassword, { 
      templateUrl: getTemplateUrl("forgotten-password.html"), 
      pageName: "Forgotten Password" 
     }) 
     .when(ROUTES.home, { 
      templateUrl: getTemplateUrl("home.html"), 
      resolve: resolve 
     }) 
     .when(ROUTES.personalDetails, { 
      templateUrl: getTemplateUrl("personal-details.html"), 
      resolve: resolve 
     }) 
     .when(ROUTES.paymentDetails, { 
      templateUrl: getTemplateUrl("payment-details.html"), 
      resolve: resolve 
     }) 
     .when(ROUTES.orders, { 
      templateUrl: getTemplateUrl("orders.html"), 
      resolve: resolve 
     }) 
     .when(ROUTES.subscriptions, { 
      templateUrl: getTemplateUrl("subscriptions.html"), 
      resolve: resolve 
     }) 
     .when(ROUTES.updatePassword, { 
      templateUrl: getTemplateUrl("update-password.html"), 
      pageName: "Update Password" 
     }) 
     .when(ROUTES.accountVerification, { 
      templateUrl: getTemplateUrl("account-verification.html"), 
      pageName: "Account Verification" 
     }) 
     .when(ROUTES.error, { 
      templateUrl: getTemplateUrl("error.html"), 
      pageName: "Error" 
     }) 
     .when(ROUTES.register, { 
      templateUrl: getTemplateUrl("register.html"), 
      pageName: "Register" 
     }) 
     .when(ROUTES.profile, { 
      templateUrl: getTemplateUrl("profile.html"), 
      resolve: resolve, 
      pageName: "Profile" 
     }) 
     .when(ROUTES.accountConfirm, { 
      templateUrl: getTemplateUrl("accountConfirm.html"), 
      pageName: "Registration Complete" 
     }) 
     .when(ROUTES.deleteAccount, { 
      templateUrl: getTemplateUrl("deleteAccount.html"), 
      resolve: resolve, 
      pageName: "Delete Account" 
     }) 
     .otherwise({ 
      templateUrl: getTemplateUrl("login.html"), 
      pageName: "Login" 
     }); 

の場合:

git clone https://github.com/angular/angular-phonecat.git 

私が最初に次の設定を使用してアプリケーションを実行しようとする問題をローカライズするにはそれは正常に動作し、StartCtrlコントローラで何か怪しげなことが起こっている。作品は正しく、その後$routeChangeErrorハンドラを探している場合

$routeProvider 
     .when('/', { 
      template: '<div>Hello</div>' 
     }) 
     .otherwise('/'); 

:まだ正常に動作しない場合は、これを試してみてください。そうでなければ、ルータイベントハンドラがあるかもしれません。ここでngRouteのイベントのリストです:$routeChangeStart$routeChangeError$routeUpdate$routeChangeSuccess

EDIT:

彼らはあなたが削除することができます戻ってクリックしたときに、ユーザーが戻って/ルートに戻るにはしたくないので、それは歴史から。 /ルートから離れてユーザーをリダイレクトするときに$locationサービスのreplace methodに電話するだけです。例えば。 $location.path('/login').replace()

+0

ありがとうアレクサンダー。あなたが正しいです - 犯人はStartCtrlコントローラです。このコントローラには、ユーザーがログインしているかどうかを確認するコードと、存在しない場合はログインビューが存在するかどうかを確認するコードがあります。したがって、ユーザーが '/'に到着すると、新しいビューが表示され、それに応じてURLが更新され、ユーザーがデフォルトビューの '/'に戻るたびにループが作成されます。私はこの機能を変更できるとは思わない。この問題を回避する方法をお勧めしますか?これ以上のコード例が必要な場合はお知らせください。 – shrewdbeans

+0

質問に問題を引き起こすstartctrlのコードを追加してください。 –

+0

これが追加されました。何か必要があれば教えてください。 – shrewdbeans

1

を有効にすることによって、#!のプリペアを無効にすることができます。私はそれがあなたの問題と互換性があるかどうかは100%確信していませんが、この方法でAngularアプリケーションを開くと、2つではなく1つの履歴イベントのように見えます。

+0

私はこれを試しましたが、本当に '#!'を削除しますが、私はまだ同じ問題があります。 Angularアプリの最初のビューから戻ると、前のURLに戻るのではなく、そのビューがリロードされます。 – shrewdbeans

関連する問題