2017-01-03 2 views
5

Bei der Entwicklung einer Web-App mit jQuery oder normalem JavaScript ist es üblich, zunächst nach der Verfügbarkeit von Funktionen zu suchen. So zum Beispiel, wenn ich das document.oncopy Ereignis verwenden möchten, sollte ich zuerst so etwas wie dieses muss meinen Code nicht gewährleistet, für kleinere Browser brechen:Angular Universal- und Browser-Funktionsüberprüfungen

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

Ich bin ein wenig verwirrt darüber, wie dies funktionieren würde in Angular2. Ich könnte immer noch das selbe verwenden, wenn ich erwarte, nur im Browser zu laufen, aber mir wird ausdrücklich gesagt, das DOM allein zu lassen, wenn ich Angular Universal verwenden möchte und stattdessen auf Vorlagen oder den DomRenderer angewiesen bin. Dadurch kann die Seite auf dem Server vorgerendert werden und bietet einen wirklich beeindruckenden Leistungsgewinn.

Aber angenommen, ich möchte ein bestimmtes Div unsichtbar sein, wenn die document.oncopy nicht verfügbar ist. Mein Verständnis ist, dass dies nicht empfohlen wird:

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

und

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

denn dann bin ich immer noch den DOM zu manipulieren. Beachten Sie, dass mein Beispiel über die document.oncopy ist, aber ich könnte jede Funktion wählen, die keine universelle Unterstützung hat.

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

Update:: Folgendes Ende seiner Startseite Vorlage

Getestet habe ich dies mit Chris Nwamba's tutorial auf Scotch und hinzugefügt Interessanterweise gab unterschiedliche Ergebnisse auf verschiedenen Browsern. In Chrome 55 wurde es wie gewohnt ausgeführt und zeigte die Meldung "Feature wird unterstützt". Auf IE11 habe ich die Nachricht "nicht unterstützt" erhalten. In beiden Fällen zeigt das Serverprotokoll eine Nachricht EXCEPTION: document is not defined, aber die Seite scheint immer noch vollkommen in Ordnung zu sein.

Was ist der richtige Weg, um nach Browserfunktionen zu suchen, wenn ich Angular Universal verwenden möchte?

Update: Ich spielte um auch mit einem Feld in der Vorlage und das Feldes von einem der life cycle hooks zuweisen. ngAfterContentInit schien ein guter Kandidat, verursacht aber auch einen Fehler auf dem Server. Es läuft immer noch gut im Browser ohne merkwürdige Effekte (die ich bisher bemerkt habe).

Antwort

0

Es gibt zwei Möglichkeiten, diesen Ansatz:

  1. Sie die Prüfung erst, wenn die Server-Rendering erfolgt und der Client vollständig initialisiert (einschließlich der Wiedergabe von Benutzerereignissen durch preboot.js getan).
  2. Geben Sie einen angemessenen Standardwert zurück, wenn die Seite auf dem Server ausgeführt wird, und führen Sie die tatsächliche Überprüfung nur im Browser durch.

begann ich bei der ersten Option suchen, aber keine der Lebenszyklusereignisse Angular2 wird dabei helfen. In der Tat können Sie deutlich sehen, dass sie alle auf dem Server und nur dann auf dem Client ausgeführt werden.

Ich begann dann auf der Suche nach etwas Brauchbarem in preboot.js, aber schnell erkannte, dass es komplexer war als es sein musste.

Also auf Option 2 ging ich.Es stellt sich heraus, dass die Überprüfung des Browsers so einfach ist wie das Importieren und Überprüfen von isBrowser.

import { isBrowser } from "angular2-universal"; 

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

Und dann die Vorlage verwenden, wie ich in der Frage zeigte.

Um zu überprüfen, ob Sie auf dem Server ausgeführt werden, importieren und verwenden Sie isNode auf genau die gleiche Weise. Es scheint keinen offensichtlichen Weg zu geben, zwischen Node und ASP.NET Core zu unterscheiden, aber vielleicht ist es am besten, nicht zu viel Code zu schreiben, der plattformspezifisch ist.

Verwandte Themen