2017-01-03 13 views
5

Podczas tworzenia aplikacji internetowej z jQuery lub zwykłym kodem JavaScript najczęściej sprawdza się dostępność funkcji. Tak na przykład, jeśli chcę użyć zdarzenia document.oncopy, powinienem najpierw coś takiego, aby zapewnić mój kod nie łamie dla mniejszych przeglądarek:Angularowe sprawdzanie cech uniwersalnych i przeglądarek

if ("oncopy" in document) { 
    // Feature is available 
} 

Jestem nieco zaskoczony, jak to będzie działać w Angular2. Mogę nadal używać tego samego, jeśli spodziewam się tylko uruchamiać w przeglądarce, ale jestem konkretnie poproszony o opuszczenie DOM sam, jeśli chcę użyć Angular Universal i zależy od szablonów lub DomRenderer zamiast. Pozwala to na wstępne renderowanie strony na serwerze i zapewnia naprawdę imponujący wzrost wydajności.

Ale przypuśćmy, że chcę, aby określony element div był niewidoczny, jeśli document.oncopy jest niedostępny. W moim rozumieniu jest to, że nie jest to zalecane:

<div *ngIf="hasFeature()">...</div> 

i

hasFeature() { 
    return 'oncopy' in document; 
} 

bo wtedy ja wciąż manipulowania DOM. Zauważ, że mój przykład dotyczy document.oncopy, ale mogę wybrać dowolną funkcję, która nie ma uniwersalnego wsparcia.

Testowałem to przy użyciu Chris Nwamba's tutorial na szkockiej i dodaje następujące do końca swojego szablonu głównego:

<div *ngIf="hasFeature()">Feature is supported</div> 
<div *ngIf="!hasFeature()">Feature is NOT supported</div> 

Aktualizacja: ciekawe, dała różne wyniki w różnych przeglądarkach. W przeglądarce Chrome 55 wykonano ją w normalny sposób i wyświetlono komunikat "Funkcja jest obsługiwana". W IE11 otrzymałem komunikat "nie obsługiwany". W obu przypadkach dziennik serwera pokazuje komunikat o błędzie EXCEPTION: document is not defined, ale strona nadal wydaje się być w porządku.

Jaki jest więc właściwy sposób sprawdzania funkcji przeglądarki, jeśli chcę korzystać z Angular Universal?

Aktualizacja: ja też bawił się wokół z użyciem pola w szablonie i przypisanie tego pola z jednego z life cycle hooks. ngAfterContentInit wydawało się być dobrym kandydatem, ale powoduje również błąd na serwerze. Nadal działa dobrze w przeglądarce bez żadnych dziwnych efektów (które zauważyłem do tej pory).

Odpowiedz

0

Istnieją dwa sposoby podejścia do tego:

  1. wykonaj sprawdzenie tylko raz serwer odbywa renderowania, a klient jest całkowicie zainicjowany (w tym powtórki wydarzeń użytkowników wykonanej przez preboot.js).
  2. Zwraca rozsądną wartość domyślną, gdy strona działa na serwerze i wykonuje faktyczne sprawdzenie tylko w przeglądarce.

Zacząłem patrzeć na pierwszą opcję, ale żadne z wydarzeń cyklu życia Angular2 nie pomogą w tym. W rzeczywistości widać wyraźnie, że wszystkie działają na serwerze, a dopiero potem na kliencie.

Potem zacząłem szukać czegoś użytecznego w preboot.js, ale szybko zdałem sobie sprawę, że jest bardziej skomplikowany, niż powinien.

Tak więc na opcję 2 poszedłem.Okazuje się, że sprawdzenie przeglądarki jest tak proste, jak importowanie i sprawdzanie isBrowser.

import { isBrowser } from "angular2-universal"; 

@Component({ 
// All the usual stuff 
}) 
export class MyComponent { 
    // ... 
    hasFeature(): boolean { 
    return isBrowser && 'oncopy' in document; 
    } 
    // ... 
} 

Następnie użyj szablonu pokazanego w pytaniu.

Aby sprawdzić, czy używasz serwera, importuj i używaj isNode w dokładnie taki sam sposób. Nie wydaje się oczywiste, aby odróżnić Węzeł i ASP.NET Core, ale może najlepiej nie pisać zbyt dużo kodu , że specyficzne dla platformy.

Powiązane problemy