2016-05-28 6 views
1

Dies ist eigentlich eine Ausgliederung von here, mit einem viel einfacheren Anwendungsfall, obwohl. Es geht darum, Angular2 mitzuteilen, dass extern hinzugefügte DOM-Elemente mit Angular-Direktiven vorhanden sind. In diesem Fall füge ich eine neue Schaltfläche hinzu, deren On-Click-Ereignis niemals gebunden ist. Ich dachte, Zone würde automatisch Änderungen in den Vorlagen ihrer Komponenten erkennen, offensichtlich nicht. Ist jemand in der Lage, diesen Code ohne den immensen Overhead zu erstellen, eine neue Komponente für die Schaltfläche zu erstellen und über DynamicLoaderComponent zu laden?Wie Angular2 RC1 über veränderte DOM wissen lassen

Hinweis: Ich habe bereits NgZone und ChangeDetectorRef hinzugefügt, um damit herumzuspielen. Beides funktionierte nicht für mich. Hier

ist ein Link zum vollständigen Beispiel bei plunkr: plnkr.co/edit/hf180P6nkxXtJDusPdLb

Und das ist ein relevanter Ausschnitt aus der Komponente:

import {Component, AfterViewInit, ChangeDetectorRef, NgZone, Renderer} from '@angular/core' 

@Component({ 
    selector: 'my-app', 
providers: [], 
template: ` 
<div> 
<p><button on-click="clickMe()">This works</button></p> 

<div id="insert-here"></div> 

</div> 
`, 
directives: [] 
}) 
export class App implements AfterViewInit { 
constructor(private ref:ChangeDetectorRef, private ngZone:NgZone, private renderer:Renderer) { 

} 

clickMe() { 
alert("Yay, it works"); 
} 

ngAfterViewInit() { 
    let newButton = document.createElement("button"); 
    newButton.setAttribute("on-click","clickMe()"); 
    let textNode = document.createTextNode("This does not"); 
    newButton.appendChild(textNode); 
    document.getElementById("insert-here").appendChild(newButton); 

    // please make my button work: 
    this.ref.detectChanges(); 
} 

} 
+0

macht Wenn alles, was Sie benötigen ein Ereignis hinzufügen, können Sie 'NewButton tun. addEventListener ('click', this.clickMe); 'ohne 'NgZone' oder' ChangeDetectorRef' zu benötigen – Abdulrahman

+0

Danke, Abdulrahman Leider gibt es mehr als das. Ich habe Dutzende von großen SVGs mit bis zu 50 verschiedenen Klickereignissen in einem SVG. Ich brauche wirklich Angular, um den Job zu machen. Eigentlich ist es etwas, das seinem Kern innewohnt: Scannen von Markup und Binding-Logik zu Direktiven. – Matt

Antwort

1

Zone nicht über das DOM überhaupt nicht interessieren. Zone patcht nur asynchrone APIs wie addEventListener(), setTimeout(), ... und überprüft dann nur das Modell auf Änderungen.

Angular geht davon aus, dass es für das DOM zuständig ist. Das DOM wird von Angular aktualisiert, wenn sich das Modell ändert, nicht umgekehrt.

Es gibt keine Möglichkeit, Angular zum Erstellen von Komponenten oder Direktiven zum Anpassen von HTML oder zum Auflösen von Bindungen für dynamisch hinzugefügtes HTML zu verwenden. Angular tut dies nur für HTML, das statisch zur Vorlage einer Komponente hinzugefügt wird.

DynamicaComponentLoader (nicht weiterentwickelt) oder ViewContainerRef.createComponent() sind die Weg für das Hinzufügen von Komponenten dynamisch.

Sie Wrapper-Element verwenden können, die es einfach deklarativ hinzufügen dynamische Komponenten wie erklärt in Angular 2 dynamic tabs with user-click chosen components (enthält auch ein Plunker Beispiel für die neue ViewContainerRef.createComponent()

+0

Danke für die Erklärung und einen Vorschlag, wie man dieses Problem löst! Andererseits muss jede Vorlage zuerst gescannt werden, so dass es möglich sein sollte, sie erneut zu scannen und ungebundene Direktiven zu erkennen. Ich nehme an, dass diese Funktion für viele Migrationen zu Angular2 erforderlich ist und mit einem Einzeiler wie $ scope gehandhabt werden könnte. $ Apply in v1. Ich denke, es lohnt sich, eine Feature-Anfrage einzureichen. – Matt

+0

Angular scannt nur die Vorlage. Dies ist bevor es dem DOM hinzugefügt wird. Angular scannt das DOM überhaupt nicht. Vor Kurzem gab es eine Feature-Anforderung zum Anwenden von '_ng_content_xxx' Klassen für dynamisch hinzugefügtes HTML, da das CSS-Scoping für solches HTML nicht angewendet wird. Dies wurde auch von Misko abgelehnt. Daher halte ich es für unwahrscheinlich, dass eine solche Veränderung eintritt. –

+1

Ok, ich verstehe. Ich habe nicht vor, ihr Ticketsystem zu überladen. Es ist sowieso ziemlich voll. Danke für die schnellen Antworten in allen angular verwandten Fragen hier auf Stackoverflow. – Matt

Verwandte Themen