问题
This is actually a spin off from here, with a much simpler use case, though. It is about how to let Angular2 know that there are externally added DOM elements containing Angular directives. In this case, I add a new click button whose on-click event is never bound. Imo I thought Zone would automatically detect any changes in the templates of their components, obviously it doesn't. Is anyone able to make that code work without the immense overhead of creating a new component for the button and load it via DynamicLoaderComponent
?
Note: I've already added NgZone
and ChangeDetectorRef
to play around with. Neither worked for me.
Here is a link to the full example at plunkr: plnkr.co/edit/hf180P6nkxXtJDusPdLb
And this is an relevant excerpt from the component:
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();
}
}
回答1:
Zone doesn't care about the DOM at all. Zone only patches async APIs like addEventListener()
, setTimeout()
, ... and then checks only the model for changes.
Angular assumes that it is in charge of the DOM. The DOM is updated by Angular when the model changed, not the other way around.
There is no way to make Angular create components or directives for matching HTML or resolve bindings for HTML added dynamically. Angular does this only for HTML added statically to the template of a component.
DynamicaComponentLoader
(deprecated) or ViewContainerRef.createComponent()
are the way to go for adding components dynamically.
You can use wrapper element that makes it easy to declaratively add dynamic components like explained in Angular 2 dynamic tabs with user-click chosen components (also contains a Plunker example for the new ViewContainerRef.createComponent()
来源:https://stackoverflow.com/questions/37497360/how-let-angular2-rc1-know-about-changed-dom