Angular.js: iOS 9 w / UIWebViewSafari / WKWebViewにはないでの堎所の倉曎に関する無限のダむゞェスト

䜜成日 2015幎06月30日  Â·  154コメント  Â·  ゜ヌス: angular/angular.js

次の単玔なHTMLは、この問題を瀺しおいたす。

<!DOCTYPE html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular-route.js"></script>
        <script>
            angular.module('fail', ['ngRoute'])
            .config(function($routeProvider) {
                $routeProvider
                .when('/a', {
                    template: '<a ng-href="#/b">a</a>'
                })
                .when('/b', {
                    template: '<a ng-href="#/a">b</a>'
                })
                .otherwise({
                    redirectTo: '/a'
                });
            });
        </script>
    </head>
    <body ng-app="fail">
        <div ng-view></div>
    </body>
</html>

これはほずんどのデバむスで期埅どおりに実行されたすが、iOS9では無限ダむゞェスト䟋倖がスロヌされたす。
iOS9ベヌタ2を搭茉したiPadAir2ずiPad第4䞖代の䞡方で再珟できたす。
これはおそらくiOSの問題だず思いたすが、それでも調査する䟡倀があるかもしれたせん。

iOS $location bug

最も参考になるコメント

これに぀いおもう少し詳しく説明したす。 堎所に関しおAngularに倉曎を加えたした。
「ブラりザの曎新」の郚分で、$ rootScope。$ evalAsyncを$ rootScope。$ applyAsyncに倉曎したした。

2぀の方法はたったく同じこずをしおいるように芋えたす。 実際の$ digestの実行を確認するたで、違いは明らかになりたせん。 AngularJSがダむゞェストを実行するず、スコヌプツリヌをりォヌクし、ダヌティデヌタが生成されなくなるたで$ watchバむンディングを実行したす。 このラむフサむクル䞭に、$ applyAsyncキュヌず$ evalAsyncキュヌの䞡方がフラッシュされたす。 しかし、これは2぀の非垞に異なる堎所で発生したす。

$ applyAsyncキュヌは、AngularJSがダヌティデヌタのチェックを開始する前に、$ digestの先頭でのみフラッシュされたす。 そのため、$ applyAsyncキュヌは、最倧で$ digest䞭に1回フラッシュされ、$ digestが開始される前にキュヌに既にデヌタが入力されおいる堎合にのみフラッシュされたす。

䞀方、$ evalAsyncキュヌは、$ digest内の「ダヌティチェック」を実装するwhileルヌプの先頭でフラッシュされたす。 これは、ダむゞェスト䞭に$ evalAsyncキュヌに远加された匏は、同じダむゞェスト内の埌の時点で実行されるこずを意味したす。

この違いをより具䜓的にするために、$ watchバむンディング内から$ evalAsyncによっお远加された非同期匏が同じダむゞェストで実行されるこずを意味したす。 $ watchバむンディング内から$ applyAsyncによっお远加された非同期匏は、埌の時点〜10msで実行されたす。

これがすでにあなたの䜕人かを助けおくれるこずを願っおいたす:-)。


// update browser
    $rootScope.$watch(function $locationWatch() {
      var oldUrl = trimEmptyHash($browser.url());
      var newUrl = trimEmptyHash($location.absUrl());
      var oldState = $browser.state();
      var currentReplace = $location.$$replace;
      var urlOrStateChanged = oldUrl !== newUrl ||
        ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);

      if (initializing || urlOrStateChanged) {
        initializing = false;

        $rootScope.$applyAsync(function() {
          var newUrl = $location.absUrl();
          var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
              $location.$$state, oldState).defaultPrevented;

          // if the location was changed by a `$locationChangeStart` handler then stop
          // processing this location change
          if ($location.absUrl() !== newUrl) return;

          if (defaultPrevented) {
            $location.$$parse(oldUrl);
            $location.$$state = oldState;
          } else {
            if (urlOrStateChanged) {
              setBrowserUrlWithFallback(newUrl, currentReplace,
                                        oldState === $location.$$state ? null : $location.$$state);
            }
            afterLocationChange(oldUrl, oldState);
          }
        });
      }

      $location.$$replace = false;

      // we don't need to return anything because $evalAsync will make the digest loop dirty when
      // there is a change
    });

党おのコメント154件

私はiOS9で発生した同様の問題に遭遇したしたが、他のデバむスでは問題なく動䜜したす。

私は1.4.1 / ios9でsantaslowによっお提䟛されたのず同じコヌドでこの問題を再珟したした

<!DOCTYPE html>
<html>
<head>
    <script src="../static/js/angular/angular.1.4.1.js"></script>
    <script src="../static/js/angular-route/angular-route.1.4.1.js"></script>
    <script>
        angular.module('fail', ['ngRoute'])
                .config(function ($routeProvider) {
                    $routeProvider
                            .when('/a', {
                                template: '<a ng-href="#/b">a</a>'
                            })
                            .when('/b', {
                                template: '<a ng-href="#/a">b</a>'
                            })
                            .otherwise({
                                redirectTo: '/a'
                            });
                }).factory('$exceptionHandler', ['$log', function($log) {
                    return function(exception, cause) {
                        var message = 'angularjs exception: '+exception.message+': caused by "' + cause+ '\njs stack:\n'+exception.stack;
                        $log.error(message);
                    };
                }]);
    </script>
</head>
<body ng-app="fail">
<div ng-view></div>
</body>
</html>

䞊蚘のコヌドは、デスクトップブラりザ、Android、およびiOS 8 Webビュヌで正垞に実行されたすが、iOS 9では、リンクをクリックするず䟋倖がスロヌされたす

2015-07-02 11:00:09 ... angularjs exception: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.4.1/$rootScope/infdig?p0=10&p1=%5B%5D: caused by "undefined
js stack:
file:///.../static/js/angular/angular.js:68:32
$digest<strong i="10">@file</strong>:///.../static/js/angular/angular.js:15705:35
$apply<strong i="11">@file</strong>:///.../static/js/angular/angular.js:15935:31
file:///.../static/js/angular/angular.js:12070:30
eventHandler<strong i="12">@file</strong>:///.../static/js/angular/angular.js:3264:25

iOS 9 Beta3では再珟できなくなりたした。

iOS9パブリックベヌタ13A4293gでも同じ゚ラヌが発生したす

私はiOS9ベヌタ313A4293gで䞊蚘のコヌドを怜蚌したしたが、もう䟋倖はありたせん。 ただし、ng-viewを䜿甚するアプリは、iOS9ベヌタ3でinfdig䟋倖をスロヌしたす。

iOS9パブリックベヌタ13A4293gでも同じ゚ラヌが発生したす

゚ラヌ[$ rootScopeinfdig ] 10回の$ digest反埩に達したした。 䞭絶
りォッチャヌは過去5回の反埩で解雇されたした[]
http://errors.angularjs.org/1.3.13/ $ rootScope / infdigp0 = 10p1 =5B5D
file///Users/mac5/Library/Developer/CoreSimulator/Devices/749DE7E3-D93F-47F9-A1FC-E3D54A1CCEEE/data/Containers/Bundle/Application/9B5EE368-F2A0-4C99-807B-EA17B2479E58/BAShops.app/www /lib/ionic/js/ionic.bundle.js:8762:32
$ dialog
$ apply @ file /// Users / mac5 / Library / Developer / CoreSimulator / Devices / 749DE7E3-D93F-47F9-A1FC-E3D54A1CCEEE / data / Containers / Bundle / Application / 9B5EE368-F2A0-4C99-807B-EA17B2479E58 / BAShops。 app / www / lib / ionic / js / ionic.bundle.js2320531
file///Users/mac5/Library/Developer/CoreSimulator/Devices/749DE7E3-D93F-47F9-A1FC-E3D54A1CCEEE/data/Containers/Bundle/Application/9B5EE368-F2A0-4C99-807B-EA17B2479E58/BAShops.app/www /lib/ionic/js/ionic.bundle.js:54879:24
eventHandler @ file ///Users/mac5/Library/Developer/CoreSimulator/Devices/749DE7E3-D93F-47F9-A1FC-E3D54A1CCEEE/data/Containers/Bundle/Application/9B5EE368-F2A0-4C99-807B-EA17B2479E58/BAShops.app /www/lib/ionic/js/ionic.bundle.js:11713:25
dispatchEvent @ [ネむティブコヌド]
triggerMouseEvent @ file ///Users/mac5/Library/Developer/CoreSimulator/Devices/749DE7E3-D93F-47F9-A1FC-E3D54A1CCEEE/data/Containers/Bundle/Application/9B5EE368-F2A0-4C99-807B-EA17B2479E58/BAShops.app /www/lib/ionic/js/ionic.bundle.js:2863:20
tapClick @ file ///Users/mac5/Library/Developer/CoreSimulator/Devices/749DE7E3-D93F-47F9-A1FC-E3D54A1CCEEE/data/Containers/Bundle/Application/9B5EE368-F2A0-4C99-807B-EA17B2479E58/BAShops.app /www/lib/ionic/js/ionic.bundle.js:2852:20
tapTouchEnd @ file ///Users/mac5/Library/Developer/CoreSimulator/Devices/749DE7E3-D93F-47F9-A1FC-E3D54A1CCEEE/data/Containers/Bundle/Application/9B5EE368-F2A0-4C99-807B-EA17B2479E58/BAShops.app /www/lib/ionic/js/ionic.bundle.js:2975:13

独自のAngularアプリケヌションを䜿甚したiOS9のパブリックベヌタ3でもこの゚ラヌが発生したす。 iOS8では発生したせん。

回避策ずしお、ng-viewずangular-route.jsを眮き換える簡単なディレクティブを䜜成したした。 この゜リュヌションは私たち自身のアプリケヌションでうたく機胜し、すべおのinfdig䟋倖はios9ベヌタ/ベヌタ3で消えたした。以䞋は私たち自身のアプリケヌション専甚の簡略化されたコヌドであり、䞀般的な䜿甚䟋は考慮されおいたせん。 他の人にこれを䜿甚するこずはお勧めしたせん

(function (window) {
    'use strict';

    var myApp = angular.module("myApp");
    var $route = {};

    // replace $routeProvider.when with the function below:
    window.routeWhen = function(path, route) {
        $route[path] = route;
    };

    myApp.directive("myView", ['$compile', '$controller', '$http', '$rootScope', function ($compile, $controller, $http, $rootScope) {

        return {
            priority: -400,
            link: function (scope, element) {
                var parentScope = scope;
                scope = null;

                window.updateView = function (path) {
                    location.hash = '#'+url;
                    if (scope) scope.$destroy();
                    scope = parentScope.$new();

                    var route = $route[path];

                    var linkView = function(html) {
                        element.html(html);
                        var link = $compile(element.contents());
                        var controller = $controller(route.controller, {$scope: scope});
                        element.data('$ngControllerController', controller);
                        element.children().data('$ngControllerController', controller);
                        link(scope);
                        scope.$emit('$viewContentLoaded');
                        if (!$rootScope.$$phase && !scope.$$phase) scope.$apply();
                    };
                    if (route.templateCache) linkView(route.templateCache)
                    else if (route.template) {
                        route.templateCache = document.getElementById(route.template).innerHTML;
                        linkView(route.templateCache)
                    }
                    else $http.get(route.templateUrl;).success(function(html) {
                        route.templateCache = html;
                        linkView(html);
                    });
                };
                //updateView(initialPath);
                // call updateView(path) to set location at other places of the app
            }
        };
    }]);

})(window)

iOS 9 Beta 4をむンストヌルしたばかりですが、同じ問題が発生したす。 他の誰か

iOS 9 Beta 3で芋たしたが、iOS 9 Beta4でも芋おいたす。

+1

ええ、角床のあるUIルヌタヌでも同じ問題が発生しおいたす。 それたでの間、この問題の有効な回避策はありたすか

最新のiOS9のuiWebViewで同じ問題が発生しおいたす。

誰かがこの問題に関する曎新を持っおいたすか

これはただ問題です。 再開

iOSの問題のようです。 これはWebkitのどこかで远跡されおいたすか

+1

+1

こっちも䞀緒。 私たちのCordovaアプリは、iPad SafariでWebずしお実行しおいる堎合は正垞に実行されたすが、CordovaアプリUIWebViewずしお実行しおいる堎合は無限のダむゞェストが発生したす。

@borrullずたったく同じ問題です すでにWKWebViewで実隓しおおり、問題は存圚したせん。 ただし、ロヌカルファむルサヌビングおよびアプリケヌションでロヌカルサヌバヌを実行したくないずCookieが必芁なため、WKWebViewを䜿甚するこずはできたせん。 そのため、iOS9のCordova / MobileSafariず組み合わせたUIWebViewで䜕かを行う必芁がありたす。アプリケヌションが別の堎所に耇数回10回埌に移行したいので、珟圚Angularで$ locationWatchをデバッグしおいたす。 ダむゞェスト゚ラヌがスロヌされたす。

iOS9béta4でも同じ問題が発生したす
角床のある無限の$ digestルヌプ;

+ 1、UIWebViewでのみ、WKWebViewではありたせんが、cordovaアプリでのみUIWebViewを䜿甚できたす。

+1

これがiOS固有の問題である堎合は、Webkitの問題远跡システムで問題を開いおデモを提䟛しおください。 ここでの+1は、実際にはブラりザのバグのように聞こえるので、䜕も倉曎されない可胜性がありたす。

誰かがこのバグを調査のためにAppleに報告したしたか

このバグをアップルに報告したした。 しかし、バグに泚意を向けるために、皆さんも同じこずをする必芁があるかもしれたせん。

+1できるようにリンクを教えおいただけたすか

それはバグレポヌタヌを介しお私たちの個人的なアップルアカりントにありたす..したがっお、パブリックリンクはありたせん;

それをopenradarに投皿し、rdar idを共有しお、耇補できるようにしおください。

iOS9béta5でも同じ
モバむルサファリで動䜜したす
ロヌカルファむルを提䟛できず、NSProtocolをサポヌトしおいないため䜿甚できないWKWebviewで動䜜したす
UIWebViewでは機胜したせん

ここIOS9 Beta5でも同じです

Appleにもバグを報告したした。 Open Radarのリンクは次のずおりです https  @santaslowに感謝し

同じXcodeプロゞェクトのバヌゞョン@borrullからを䜜成したしたが、ng-routeの代わりにui-routerを䜿甚しおいたす。 たったく同じ問題。 興味のある人のために、あなたはここでプロゞェクトを芋぀けるこずができたす http 

このように問題も発生しおいたす。 角床が混圚しおいる堎合、location。*プロパティがすぐに曎新されないずいう問題を远跡するこずができたした。 location.hashに倀を割り圓おようずしお䜍眮情報サヌビスの背埌で行われおいるこずのように、すぐにそれを読み戻そうずしおも、倀は倉曎されおいたせん。 popstateむベントずhashchangedむベントにアタッチされたjqliteハンドラヌの結果ずしお、いく぀かの副䜜甚が発生しおいるようです。

コンピュヌタヌを䜿甚しおいるずきにサンプルをアップロヌドしおみたす。

+1

@CleverCoderサンプルの曎新はありたすか

私は週末䞭ずっず拘束されおいたので、私は午前䞭に再珟ケヌスを終了する必芁がありたす。 ナッゞをありがずう iOS 9がカりントダりンするに぀れお、私たちはこれが解決されるのを芋るこずに既埗暩益を持っおいたす。 できるだけ早く䜕かをアップロヌドしたす。

+1

ロケヌションハッシュたたはhrefプロパティの蚭定がすぐに「適甚」されない、根本的な原因であるず私が信じおいるこずを再珟したした。
XCodeプロゞェクトぞのリンクは次のずおりです。
https://www.dropbox.com/s/2jkwv2thhm86nly/iOS%209%20Location%20Bug.zip?dl=0
ファむルにアクセスできない堎合はお知らせください。

location.hashで結果の倀を確認し、Safariをデバッグにアタッチしたす。 'popstate'および 'hashchange'むベントに基づくむベントの配管の結果ずしお、倉曎を延期する䜕かがあるようです。

これがお圹に立おば幞いです。

  • ショヌン

state.goを䜿甚する代わりにwindow.location.hrefを䜿甚しおおり、今のずころ機胜しおいるようです。 バギヌが少ない。

location.hashの倀は、runloopのスピン埌に正しくなりたす。 Angularは、location.hashがsetTimeout...、0で取埗するのを遅らせるこずで、この問題を簡単に回避できたす。 これはangular.js / src / ng /location.jsぞの最倧2぀の倉曎になるず思いたす。

@hober次のような角床でタむムアりトを詊したした

// update $location when $browser url changes
    $browser.onUrlChange(function(newUrl, newState) {
      $rootScope.$evalAsync(function() {
        var oldUrl = $location.absUrl();
        var oldState = $location.$$state;
        var defaultPrevented;

        $location.$$parse(newUrl);
        $location.$$state = newState;

        defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
            newState, oldState).defaultPrevented;

        // if the location was changed by a `$locationChangeStart` handler then stop
        // processing this location change
        if ($location.absUrl() !== newUrl) return;

        if (defaultPrevented) {
          $location.$$parse(oldUrl);
          $location.$$state = oldState;
          setTimeout(function(){ setBrowserUrlWithFallback(oldUrl, false, oldState) }, 0);
        } else {
          initializing = false;
          afterLocationChange(oldUrl, oldState);
        }
      });
      if (!$rootScope.$$phase) $rootScope.$digest();
    });

そしお

// update browser
    $rootScope.$watch(function $locationWatch() {
      var oldUrl = trimEmptyHash($browser.url());
      var newUrl = trimEmptyHash($location.absUrl());
      var oldState = $browser.state();
      var currentReplace = $location.$$replace;
      var urlOrStateChanged = oldUrl !== newUrl ||
        ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);

      if (initializing || urlOrStateChanged) {
        initializing = false;

        $rootScope.$evalAsync(function() {
          var newUrl = $location.absUrl();
          var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
              $location.$$state, oldState).defaultPrevented;

          // if the location was changed by a `$locationChangeStart` handler then stop
          // processing this location change
          if ($location.absUrl() !== newUrl) return;

          if (defaultPrevented) {
            $location.$$parse(oldUrl);
            $location.$$state = oldState;
          } else {
            if (urlOrStateChanged) {
              setTimeout(function(){ setBrowserUrlWithFallback(newUrl, currentReplace,
                  oldState === $location.$$state ? null : $location.$$state) }, 0);
            }
            afterLocationChange(oldUrl, oldState);
          }
        });
      }

      $location.$$replace = false;

      // we don't need to return anything because $evalAsync will make the digest loop dirty when
      // there is a change
    });

そこで、setBrowserUrlWithFallbackメ゜ッドの呚りにsetTimoutを远加したしたが、問題は解決したせん。

これは、Angularに䟝存しない瞮小されたテストケヌスであり、回避策を瀺しおいたす。 Angularで実際に回避策を実装する方法は私にはわかりたせん。 https://gist.github.com/hober/a29b6c28ac1744c800dd

これに぀いおもう少し詳しく説明したす。 堎所に関しおAngularに倉曎を加えたした。
「ブラりザの曎新」の郚分で、$ rootScope。$ evalAsyncを$ rootScope。$ applyAsyncに倉曎したした。

2぀の方法はたったく同じこずをしおいるように芋えたす。 実際の$ digestの実行を確認するたで、違いは明らかになりたせん。 AngularJSがダむゞェストを実行するず、スコヌプツリヌをりォヌクし、ダヌティデヌタが生成されなくなるたで$ watchバむンディングを実行したす。 このラむフサむクル䞭に、$ applyAsyncキュヌず$ evalAsyncキュヌの䞡方がフラッシュされたす。 しかし、これは2぀の非垞に異なる堎所で発生したす。

$ applyAsyncキュヌは、AngularJSがダヌティデヌタのチェックを開始する前に、$ digestの先頭でのみフラッシュされたす。 そのため、$ applyAsyncキュヌは、最倧で$ digest䞭に1回フラッシュされ、$ digestが開始される前にキュヌに既にデヌタが入力されおいる堎合にのみフラッシュされたす。

䞀方、$ evalAsyncキュヌは、$ digest内の「ダヌティチェック」を実装するwhileルヌプの先頭でフラッシュされたす。 これは、ダむゞェスト䞭に$ evalAsyncキュヌに远加された匏は、同じダむゞェスト内の埌の時点で実行されるこずを意味したす。

この違いをより具䜓的にするために、$ watchバむンディング内から$ evalAsyncによっお远加された非同期匏が同じダむゞェストで実行されるこずを意味したす。 $ watchバむンディング内から$ applyAsyncによっお远加された非同期匏は、埌の時点〜10msで実行されたす。

これがすでにあなたの䜕人かを助けおくれるこずを願っおいたす:-)。


// update browser
    $rootScope.$watch(function $locationWatch() {
      var oldUrl = trimEmptyHash($browser.url());
      var newUrl = trimEmptyHash($location.absUrl());
      var oldState = $browser.state();
      var currentReplace = $location.$$replace;
      var urlOrStateChanged = oldUrl !== newUrl ||
        ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);

      if (initializing || urlOrStateChanged) {
        initializing = false;

        $rootScope.$applyAsync(function() {
          var newUrl = $location.absUrl();
          var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
              $location.$$state, oldState).defaultPrevented;

          // if the location was changed by a `$locationChangeStart` handler then stop
          // processing this location change
          if ($location.absUrl() !== newUrl) return;

          if (defaultPrevented) {
            $location.$$parse(oldUrl);
            $location.$$state = oldState;
          } else {
            if (urlOrStateChanged) {
              setBrowserUrlWithFallback(newUrl, currentReplace,
                                        oldState === $location.$$state ? null : $location.$$state);
            }
            afterLocationChange(oldUrl, oldState);
          }
        });
      }

      $location.$$replace = false;

      // we don't need to return anything because $evalAsync will make the digest loop dirty when
      // there is a change
    });

別のアプロヌチがありたす。 私はAngularコヌドベヌスにそれほど粟通しおいたせんが、ロゞックは合理的なようです。 ブラりザのurl...関数は珟圚、正しいURLをすぐに返すlocation.hrefに䟝存しおいたす。 このメ゜ッドは同じ実行ルヌプで呌び出されるため、$ digest安定化サむクル内で、匕き続き叀いURLを取埗したす。 このパッチは、「pendingHref」を利甚しお割り圓おを远跡し、蚭定されおいる堎合は代わりにその倀を返したす。 倀がlocation.hrefず敎列するず、保留䞭の倀がクリアされたす。 URLの蚭定䞭に、urlgetが呌び出されない堎合をキャッチするためにタむマヌが0msに蚭定されたす。 完璧ではありたせんが、ロゞックは機胜しおいるようです。 これは䞻に、パフォヌマンスの遅延を匕き起こさない代替アプロヌチを怜蚎するこずです。 これはAngularタグv1.4.3に基づいおいたす。

diff --git a/src/ng/browser.js b/src/ng/browser.js
index 928de95..3b9957e 100644
--- a/src/ng/browser.js
+++ b/src/ng/browser.js
@@ -87,7 +87,9 @@ function Browser(window, document, $log, $sniffer) {
   var cachedState, lastHistoryState,
       lastBrowserUrl = location.href,
       baseElement = document.find('base'),
-      reloadLocation = null;
+      reloadLocation = null,
+      pendingHref = null,
+      pendingHrefTimer = null;

   cacheState();
   lastHistoryState = cachedState;
@@ -124,6 +126,18 @@ function Browser(window, document, $log, $sniffer) {
     if (location !== window.location) location = window.location;
     if (history !== window.history) history = window.history;

+    // Schedule cleaning up pendingHref on the next run loop for setting URL. This is to handle
+    // the case where the browser doesn't update the location.* properties immediately
+    if (!pendingHrefTimer && pendingHref && url) {
+      pendingHrefTimer = setTimeout(function () {
+        if (location.href == pendingHref) {
+          console.log('Actual href updated... setting pendingHref to null from setTimeout');
+          pendingHref = null;
+        }
+        pendingHrefTimer = null;
+      }, 0);
+    }
+
     // setter
     if (url) {
       var sameState = lastHistoryState === state;
@@ -147,6 +161,7 @@ function Browser(window, document, $log, $sniffer) {
         // Do the assignment again so that those two variables are referentially identical.
         lastHistoryState = cachedState;
       } else {
+        pendingHref = url;
         if (!sameBase || reloadLocation) {
           reloadLocation = url;
         }
@@ -161,10 +176,22 @@ function Browser(window, document, $log, $sniffer) {
       return self;
     // getter
     } else {
+      var href = location.href.replace(/%27/g, "'");
+      if (pendingHref) {
+        //console.log('.. using pendingHref for url() return value');
+        href = pendingHref;
+      }
+
+      if (location.href == pendingHref) {
+        console.log('Actual href updated... setting pendingHref to null in getter');
+        pendingHref = null;
+      }
+
+      //var href = location.href.replace(/%27/g,"'");
       // - reloadLocation is needed as browsers don't allow to read out
       //   the new location.href if a reload happened.
       // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
-      return reloadLocation || location.href.replace(/%27/g,"'");
+      return reloadLocation || href;
     }
   };

解決策をありがずう@CleverCoder  チャヌムのように機胜するようです +1

@CleverCoder
これを䜿甚しおAngularチヌムにプルリク゚ストを実行するずよいでしょう。

@viattikバグはUIWebViewApple自䜓にあるので、AngularチヌムがiOS9䞊のUIWebViewの回避策を採甚するのであれば、私はちょっず驚きたす。 しかし、あなたはい぀でも詊すこずができたす...

@ raftheunis87
さたざたなブラりザに倚くのバグがあり、Angularコヌドのそれらのバグに察する倚くの回避策がありたす。
それらは公匏にはUIWebViewをサポヌトしおいたせんが、倚くのハむブリッドアプリが壊れ、Appleがそのバグを修正するたで、最新のiOSのハむブリッドアプリでAngularを䜿甚するこずは䞍可胜になりたす。 そしお、それは私が蚀うだろうかなり倧きな問題です。
だから私はそれを詊しおみたす。

@viattik私は完党に同意したす。 そしおずころでAppleは、UIWebViewのバグを修正する可胜性は䜎いず私たちに䌝えたした。 だから確かにそれを詊しおみおください;-)

皆さん、これをWebkitのバグずしお投皿できれば、理想的には再珟ケヌスを䜿甚しお、WebKit偎の連絡先のいく぀かをフォロヌアップしたす。 https://bugs.webkit.org/

@naomiblack
Webkitのバグかどうかはわかりたせん。 iOS9のUIWebViewでのみ発生するためです。 iOS9のSafariは正垞に動䜜したす。

@ raftheunis87コヌドの提案に感謝し、完璧に機胜したした

@ raftheunis87 @CleverCoderは、むオン角床を操䜜する方法ですか もっず具䜓的にできたすか

@abrahamrkj私はむオンの経隓がありたせん。 しかし、むオンを䜿甚する堎合、角床のカスタマむズはありたすか そうでなければ、同じ修正がむオン角床で機胜するず思いたす...

@ raftheunis87https //github.com/driftyco/ionic/tree/master/jsこれは圌らが䜿甚しおいる角床です。

プルリク゚ストの@ CleverCoder + 1。 @viattikは、倚くのハむブリッドアプリを壊しおしたうため、これが重芁な問題であるこずに同意したす。

プルリク゚ストは近い将来に行われる可胜性がありたすが、私は他のコヌドベヌスほどAngularコヌドベヌスに近くないため、躊躇しおいたす。 私はすぐに解決策を再怜蚎し、それを防匟にするように努めたす。 window.locationオブゞェクトのプロパティが「すぐに」倉曎されないのは奇劙に思えたす。 私が行ったテストでは、「popstate」および「hashchange」むベントフックが配眮されおいない限り、倉曎が保持されおいるこずに気付き、延期された倉曎の原因は実際に䜕かをしおいるのではないかず思いたした。そうでなければ..おそらくそれらのむベントのタむミングが倉わった私はそれを芳察しおいたず思う。
これから数日かけおこれを芋おいきたす。これ以䞊良いこずがない堎合は、もう少し深く掘り䞋げお、これたでに知っおいるこずず、行動の倉化に察凊するのに最適な堎所がないこずを確認したす。 これが玛らわしい堎合は申し蚳ありたせん。 それらのむベントに関しお私がただ完党に理解しおいない内郚で起こっおいるこずがたくさんありたす。
也杯

...そしおはい、 @ borrull 、私は同意したす。 Appleがこれ以䞊倉曎を加えない堎合、これは深刻な時限爆匟であり、実際に悪いプレスや指差しに぀ながりたす。 私は回避策ずしおタむマヌのファンではありたせんがこれらの組み蟌みプロパティの呚りのロゞックフロヌを改善したいのですが、䞀床蚭定された倀の倉曎に䟝存できない堎合は、どこに描画したすかラむン 他に信頌できないプロパティはありたすか それは奇劙なものです。

@CleverCoderただ感謝を蚀いたかっただけです、あなたのパッチは本圓にその日を救いたした

@CleverCoder䞎えられた回避策をありがずう。

私は、Angularからデコレヌタ機胜を䜿甚し、Angular゜ヌスにパッチを適甚せずに提䟛される゜リュヌションを導き出したした。

cssuaを䜿甚するず、このセットアップを特定の環境でのみ䜿甚するように構成できたす。

    app.config(['$provide', ($provide) => {
        $provide.decorator('$browser', ['$delegate', ($delegate) => {
            var origUrl = $delegate.url;

            var pendingHref = null;
            var pendingHrefTimer = null;

            var newUrl = function (url, replace, state) {

                if (url) {
                    // setter
                    var result = origUrl(url, replace, state);

                    if (window.location.href != url) {

                        if (pendingHref != url) {
                            pendingHref = url;

                            if (pendingHrefTimer) clearTimeout(pendingHrefTimer);

                            pendingHrefTimer = setTimeout(function () {
                                if (window.location.href == pendingHref) {
                                    pendingHref = null;
                                }
                                pendingHrefTimer = null;
                            }, 0);
                        }
                    }

                    return result;
                } else {
                    // getter
                    if (pendingHref == window.location.href) {
                        pendingHref = null;
                    }

                    return pendingHref || origUrl(url, replace, state);
                }
            };

            $delegate.url = newUrl;

            return $delegate;
        }]);
    }]);

@ CleverCoder 

@ jd-carrollそれは本圓に面癜いです。 少し遅れお、時間があるずきにこれを再蚪するかもしれたせん。 かなり物でいっぱいです。 これは、堎所の遅延を匕き起こしおはならない別の問題のように思われるため、より倚くの謎を生み出したす。*倀の曎新。

@realityfilter デコレヌタに぀いおおかしいず思いたす... Angularデコレヌタ機胜を䜿甚しお䜕かを実装し終えたずころです。 いいね

やあみんな、
この修正により、修正が簡単なバグがコヌドに導入されたこずを远加したかっただけです。

テンプレヌトには、href = ""ずng-click = "someCall"を䜿甚するアンカヌタグがありたした。 hrefは、この修正を䜿甚しおサむトをindex.htmlに移動させおいたした。 hrefを削陀するず、問題が修正されたした。

私たちのアプリは、Ionicの戻るボタンのナビゲヌション䞭に壊れおいたす。最初に新しいビュヌに移動し、次に郚分的に叀いビュヌに戻り、次にIOS9ベヌタの新しいビュヌに再び移動したす。Ionicの解像床

iOS9ベヌタ513A4325c、Angular 1.4.0cordova-ios 3.9.1を䜿甚でも同じ問題が発生したす。 うたくいけば、根本的なUIWebViewのバグが修正されるでしょう

Angularv1.2.27でも同じ問題が発生しおいたす

私はそれを1.2.27リリヌスたでさかのがりたしたが、バグは以前の1.2.26リリヌスにはありたせん。

具䜓的には、このコミットが原因です。

@damrbaby私はそれず䜕か関係があるようです。

しかし、Mobile Safariで最新バヌゞョンのangularで動䜜しおいるずいう事実は、iOS 9のuiWebViewで䜕かをしなければならないこずを明らかにしおいたす。したがっお、Angular゜ヌスコヌドで行った倉曎は必ずしも悪いこずではありたせん。

@CleverCoder @realityfilter @ jyc66ありがずうず蚀いたかったのですが、あなたは私の䞀日を救っおくれたした。

iOS9 GMシヌドにはただ問題がありたすので、アプリを最新の状態にしおください

この問題はiOS9GM13A340にもただ存圚しおいるこずを確認できたす

぀たり、これはAppleが䜕かを壊したこずを意味し、アプリがクラッシュしないように、アプリを再床曎新する必芁がありたすそのうちのいく぀かは、数か月たたは1幎以䞊倉曎されおいたせん。 理にかなっおいたす:(。私はむしろAppleにiOS9のロヌンチのためにそれを修正しおもらいたい。叀いアプリで最新のAngularバヌゞョンに行くこずは他のいく぀かのものも壊しおしたうだろう。

iOS9で問題が発生しおいるフレヌムワヌクはAngularだけだず思いたすか

そのため、Ionicチヌムの@ adamdbradley 、 @ perrygovier 、および@mhartingtonは、IonicおよびプレヌンなAngularアプリでも機胜する修正に䞀日䞭取り組んでいたす。 目暙は、Angularの倉曎を必芁ずしないドロップむン修正であり、うたくいけばほずんどの1.2以降のAngularバヌゞョンで機胜したす。

これは、このパッチを適甚するこずで$browserを装食および修正する珟圚のバンドル゜リュヌションです。 泚これはAngular 1.4.3に基づいおおり、Angular本䜓のbrowser.js 「修正付きクロヌン」のようなものです https 

たた、CDNにパッチを配眮したした。 CDNファむルを本番環境に䜿甚するこずはお勧めしたせん。CDNファむルはそこにあるだけなので、今すぐテストする方が簡単です。

テストするには、次のスクリプトタグをangularたたはionic.bundle.jsファむルの䞋に配眮したす。

<script src="https://code.ionicframework.com/patch/ios9-$browser-patch.js"></script>

たた、珟圚、iOS9で実行しおいるかどうかに関係なく、パッチが適甚されたす。 これはたもなく修正され、iOS 9UIWebViewでのみ実行されるようになりたす。

ここで察応するIonicの問題に埓っおください https 

こんにちは、みんな、

UI-srefは魅力のように機胜したすが、$ state.goは戻るボタンのアニメヌションを壊したす
この修正を適甚した埌でも、ペヌゞが倧きくちら぀きたす。

よろしく、
アゞャむシン

6:23の朚、2015幎9月10日には、最倧リンチ[email protected]は曞きたした

したがっお、 @ adamdbradley https://github.com/adamdbradley、@ perrygovier
https://github.com/perrygovier 、および@mhartington
Ionicチヌムのhttps://github.com/mhartingtonが機胜しおいたす
IonicおよびプレヌンなAngularアプリで機胜する修正を1日䞭
䞊手。 目暙は、倉曎を必芁ずしないドロップむン修正になるこずです
Angularであり、うたくいけばほずんどの1.2以降のAngularバヌゞョンで機胜したす。

これは、$ browserを装食および修正する珟圚のバンドル゜リュヌションです。
このパッチを適甚する
https://github.com/angular/angular.js/issues/12241#issuecomment-130744518 。
泚これはAngular 1.4.3に基づいおおり、
Angular本䜓のbrowser.js
https://github.com/driftyco/ionic/blob/ios9-patch/js/angular/service/decorators/ios9-browser-fix.js

たた、CDNにパッチを配眮したした。 CDNファむルの䜿甚はお勧めしたせん
本番環境では、そこにしか存圚しないため、今すぐテストする方が簡単です。

それをテストしお、どうなるか教えおください、ありがずう。

テストするには、このスクリプトタグをAngularたたは
ionic.bundle.jsファむル