AngularJS i różne przeglądarki..
AngularJS to framework MVC napisany w JavaScrpit (wspierany między innymi przez Google). Framework ten nadaje się świetnie do tworzenia złożonych interfejsów użytkownika z użyciem javasciptu. W W firmie w której obecnie pracuje mamy za sobą udane wdrożenie tego frameworka do naszego panelu klienta.
Twórcy AngularJS chwalą się tym że ich framework jest przenośny i kompatybilny z większością przeglądarek obecnych na rynku. Może być to prawdą jeśli weźmiemy pod uwagę tylko najnowsze wydania. Poniżej przedstawiam w jaki sposób nie tracą kilku dni sprawić by kilka najczęściej spotykanych problemów znikło.
Firefox 3.0.x
1. Firefox 3.0.x nie posiada wbudowanego wsparcia dla JSONa, najlepiej skorzystać z biblioteki JSON2. Uwaga, biblioteka JSON3 mimo zapewnień autora nie działa pod firefoxem 3.0.x.
<script src="/media/app2/lib/json3.min.js"></script> |
2. Zamień wszystkie tagi AngularJS na divy. Zamiast używać
(ta wersja Firefoxa nie wspiera tak zaawansowanych selektorów).
3. Dla tej wersji Firefox należy dodać id=”ng-app” do tagu HTML:
<html id="ng-app" ng-app="app-name"> |
Zamiast app-name należy podać nazwę naszej aplikacji. Uwaga, jeśli również dodamy class=”ng-app” to wtedy AngularJS nie uruchomi się…
Internet Explorer 8
Należy dodać wsparcie dla nieistniejących tagów HTML dostarczanych przez AngularJS.
<!--[if lte IE 8]> <script> document.createElement('ng-include'); document.createElement('ng-pluralize'); document.createElement('ng-view'); document.createElement('ng:include'); document.createElement('ng:pluralize'); document.createElement('ng:view'); </script> <![endif]--> |
Internet Explorer 7
1. W Internet Explorer 7 brakuje wbudowanego wsparcia dla JSONa, najlepiej skorzystać z biblioteki JSON2
2. W IE7 należy zmodyfikować tag HTML, tab by posiadał id=”ng-app”, oraz zarejestrowaną przestrzeń nazw NG.
<!--[if IE 7 ]><html id="ng-app" ng-app="app-name" xmlns:ng="http://angularjs.org"><![endif]--> |
3. W Internet Explorer 7 podobnie jak w Firefox 3 – nie ma wbudowanej obsługi JSON, należy również skorzystać z biblioteki JSON2.
<!--[if lte IE 7]> <script src="json3.min.js"></script> <![endif]--> |
4. Tak samo jak w przypadku Internet Explorer 8 dodajemy wsparcie dla niestandardowych tagów z których korzysta AngularJS:
<!--[if lte IE 8]> <script> document.createElement('ng-include'); document.createElement('ng-pluralize'); document.createElement('ng-view'); document.createElement('ng:include'); document.createElement('ng:pluralize'); document.createElement('ng:view'); </script> <![endif]--> |
Internet Explorer raz jeszcze…
1. Bardzo często Internet Explorer przełącza się do trybu zgodności ze swoimi starszymi kolegami. Warto upewnić się że IE zawsze będzie działo w najnowszym trybie.
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
Niestety bardzo często przeglądarka ignoruje taki zapis. Można się o tym samemu przekonać włączając tryb develop (kalwisz F12). W sekcji konsola znajduje się informacja że instrukcja META X-UA-Compatible została pominięta… Najlepszym rozwiązaniem jest wysyłanie X-UA-Compatible w nagłówku odpowiedzi serwera.
2. Domykanie tagów – jeśli gdzieś zostawimy jakiś niezamknięty tag HTML np. możemy być pewni że AngularJS w tym miejscu przestanie przetwarzać dalszą część szablonu.
Uncaught Error: 10 $digest() iterations reached.
Uncaught Error: 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [["fn:$locationWatch; newVal: 6; oldVal: 5"],["fn:$locationWatch; newVal: 7; oldVal: 6"],["fn:$locationWatch; newVal: 8; oldVal: 7"],["fn:$locationWatch; newVal: 9; oldVal: 8"],["fn:$locationWatch; newVal: 10; oldVal: 9"]] |
Dość często spotykany błąd niezależnie od przeglądarki (trochę rzadziej występuje na Chrome, zależy bardziej od zasobów komputera). W większości przypadków występuje gdy korzystamy z takiej konfiguracji routeProvider:
config(['$routeProvider', function($routeProvider) { $routeProvider. when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}). when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}). otherwise({redirectTo: '/phones'}); |
Przyczyna leży w redirectTo. Zamiast korzystać z otherwise({redirectTo: ‚/phones’}); najlepiej stworzyć domyślny widok do którego będą wpadały wszystkie nieobsługiwane „akcje”.
Postscriptum
Dość przydatną rzeczą jest śledzenie błędów które występują bezpośrednio u użytkownika w przeglądarce. Jak to zrobić można przeczytać w artykule opisującym użycie Raven-JS i sentry.
Preview: