2015-05-01 5 views
6

Unsere Angular.js Web App friert manchmal auf iOS8 Safari ein. Wenn dieses Problem auftritt, wird der ng-Klick-Rückruf nicht ausgelöst. Wenn Sie ng-click mit einem normalen Javascript onclick ersetzen, würde es funktionieren. In Chrome auf iOS8-Geräten ist dies nicht der Fall.Angular.js Mobile Browser App friert auf iOS 8 ein Safari

Hat jemand anderes dieses Problem auf iOS8 Safari bemerkt oder hat es eine Lösung dafür?

Diese einfache Ansicht friert manchmal auf iOS8 Safari ein. Das Einfrieren tritt normalerweise auf, wenn Sie den Tab geöffnet haben, zu anderen Tabs im Browser wechseln oder vielleicht die Browser-Erfahrung verlassen und später wiederkommen. In diesem Beispiel, wenn die Ansicht beim Antippen der Links einfriert, wird tapCount nicht erhöht. Je komplizierter die Ansicht, desto leichter wird es einzufrieren. In diesem Beispiel würde der Browser für ein paar Sekunden einfrieren, wenn ich schnell auf die Links klicke. Gewöhnlich dauert das Einfrieren bei wirklich komplizierten Ansichten länger.

var app = angular.module('myApp', []); 
 
app.controller('freezeCtrl', function($scope) { 
 
    $scope['tapCount'] = 0; 
 

 
$scope['dummyItems'] = []; 
 
for(var i = 0; i < 15; i++) { 
 
    var anItem = {'id': i}; 
 
    ($scope['dummyItems']).push(anItem); 
 
} 
 

 
$scope['updateTapCount'] = function() { 
 
    $scope.tapCount += 1; 
 
}; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> 
 
<div ng-app="myApp"> 
 
    <div ng-controller="freezeCtrl"> 
 
    <p>Tap Count = {{tapCount}}</p> 
 
    <ul> 
 
     <li ng-repeat="item in dummyItems" bindonce> 
 
      <p>This is a dummy item #{{item.id}}</p> 
 
     </li> 
 
    </ul> 
 
    <div> 
 
     <button ng-click="updateTapCount()">Button 1</button> 
 
     <button ng-click="updateTapCount()">Button 2</button> 
 
    </div> 
 
    </div> 
 
</div>

+0

Können Sie ein Beispiel für die einfachste App posten, wenn Sie dieses Verhalten sehen? – xpereta

+0

Hallo Xpereta, ich habe ein sehr einfaches Beispiel hinzugefügt, wo ich in der Lage gewesen bin, das Einfrieren für eine Minute oder mehr zu wiederholen. –

Antwort

2

fand ich die Lösung und scheint, wie ich die Lösung rechts über die Zeit, jemand anderes ist der Fehler in Angular gefunden! Es ist in Angular 1.3.x behoben.

Der Fehler ist bei "isArrayLike" in angular.js Code. Manchmal ist obj.length nach der Zuweisung nicht definiert "var length = obj.length;" variable Länge erhält den Wert "1". Dies würde dazu führen, dass isArrayLike true für Objekte zurückgibt, die nicht ArrayLike sind. Insbesondere dieser Bug würde die Winkel für forEach und später für den "eventHandler" von JQLite brechen. Daher würden keine Ereignishandler ausgeführt werden, wenn dies passierte.

+0

Dies ist der Webkit-Fehler: http://trac.webkit.org/changeset/182058/trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h –

+1

Die Implementierung von isArrayLike n 1.2.x und 1.3.x ist identisch mit der Verwendung der globalen Variable . Ich sehe, Sie erwähnt Webkit Problem für Phantom object.length -Eigenschaft - Haben Sie einen Hinweis, wie dies in 1.2.x Patch/Workaround sein könnte? –

+0

Überraschenderweise machte die eine Linie einen großen Unterschied. Manchmal - nicht immer - auf iOS8 Safari nach der Zuweisung "Länge" erhält den Wert 1, während obj.length nicht definiert ist. Dies scheint durch einen JIT-Fehler verursacht worden zu sein. Dies würde dazu führen, dass isArrayLike true für Objekte zurückgibt, die nicht ArrayLike sind, was dazu führen würde, dass das Objekt "forEach" beim Iterieren über Objektschlüssel fehlschlägt, weil die Prüfung auf isArrayLike für jede Implementierung an erster Stelle steht. forEach versäumt, über Obj-Schlüssel zu iterieren, würde dazu führen, dass die Obj-Ereignishandler nicht ausgeführt werden, wenn forEach forEach (eventHandlersCopy, ..) bei createEventHandler aufgerufen wird. –