nativeelement - Componente de Angular 2: acceso a DOM(o crear componente sin plantilla, únicamente desde JS)
renderer2 (5)
Intentando jugar con Angular 2 aquí ... entendí que todavía está en alfa.
¿Cómo accedo a los elementos DOM desde el componente? Específicamente, me gustaría usar otras bibliotecas como d3 para generar un DOM personalizado a partir del código. Supongo que necesito crear un componente y conectarlo de alguna manera en el ciclo de vida de los componentes para alterar DOM con d3 ... ¿alguna idea de dónde empezar a cavar?
Estoy usando este repositorio de inicio rápido .
¡Gracias!
Usa ElementRef
ElementRef inyectará el nodo DOM actual en su componente. El servicio ElementRef siempre será local a su nodo DOM actual.
Una vez inyectado, puede obtener el nodo DOM real usando nativeElement:
var el = elementRef.nativeElement
Una vez que tenga esto, puede manipularlo de la forma que desee, ya sea utilizando scripts DOM o utilizando un contenedor DOM como jQuery:
$(el)
.append(''<p>Some interesting Stuff'')
.addClass(''my_class'');
Pero no hagas esto si puedes evitarlo.
Tenga en cuenta que, al igual que con Angular 1, se desaconseja el uso de la manipulación directa de DOM. Puede hacer prácticamente todo su trabajo utilizando plantillas, y debería favorecer esta forma de trabajar la mayor parte del tiempo.
La manipulación directa de DOM lleva a un código complicado, difícil de entender, difícil de probar.
Hay veces, sin embargo, cuando puede parecer la mejor solución. Por ejemplo, si tiene que integrarse con un marco de terceros de alta complejidad como una biblioteca de gráficos.
Aquí hay un ejemplo trabajado (en ES6)
var AppComponent = ng.core
.Component({
selector: "app",
template:
`
<div>Captured element</div>
`
})
.Class({
constructor: [ng.core.ElementRef, function(elementRef) {
var el = elementRef.nativeElement
el;
}]
})
Como han mencionado otros carteles: puede manipular el DOM inyectando ElementRef
en la directiva. Sin embargo, considere cuidadosamente si realmente necesita hacer esto.
D3 es una herramienta de manipulación de DOM. Le permite vincular un objeto de datos a un nodo DOM, luego agregar o eliminar elementos secundarios de ese elemento en respuesta a los valores de datos cambiantes. Esto es casi exactamente lo que hace Angular 2.
Por supuesto, D3 también hace otras cosas. Puede generar ángulos para un gráfico circular, o una distribución normal, por ejemplo, y es posible que desee usar D3 para esto.
Sé que no es la respuesta que estás buscando. No es la respuesta que estaba buscando, pero ... Considere cuidadosamente si necesita usar D3 para la manipulación de DOM y el enlace de datos. Angular 2 ya tiene manipulación de DOM y enlace de datos.
Este documento ( http://victorsavkin.com/post/118372404541/the-core-concepts-of-angular-2 ) menciona "directivas de estilo decorador" que creo que se describen con un poco más de detalle y un ejemplo básico aquí ( https://angular.io/api/core/Directive ).
Nota: [En desuso]
Puede utilizar "BrowserDomAdapter"
https://angular.io/docs/ts/latest/api/platform/browser/BrowserDomAdapter-class.html
import {BrowserDomAdapter} from ''angular2/platform/browser''
@Component({
selector: ''dom'',
templateUrl: ''path/to/template.html'',
providers: [BrowserDomAdapter]
})
export class DomComponent {
constructor(private _dom: BrowserDomAdapter) {
var domIWant = this._dom.query(''whatever you want to get'');
}
}
Proceso
- importar BrowserDomAdapter
- aplicar proveedores: [BrowserDomAdapter]
- iniciar en constructor ()
- obtener dom utilizando el navegador de navegador de instancia
Si no le importa usar la directiva en lugar del componente, es sencillo. Para Angular 2.0.0-alpha.33 en mecanografía, puede usar D3 para manipular el DOM inyectando un ElementRef:
@Directive({
selector: ''scatter-plot'',
lifecycle: [LifecycleEvent.onChange],
properties: [ ''data'' ]
})
export class ScatterPlot {
root: Selection<any>;
data: Array<ScatterPlotDataPoint>;
x: (number) => number;
y: (number) => number;
defaultSize: string;
circles: any;
constructor(
@Inject(ElementRef) elementRef: ElementRef,
@Attribute(''height'') height: string,
@Attribute(''default-size'') defaultSize: string
) {
var el:HTMLElement = elementRef.nativeElement;
this.root = d3.select(el);
this.defaultSize = defaultSize ? defaultSize : "5";
this.circles = this.root
.append(''svg'')
.attr(''class'', ''chart'')
.style({
''width'': ''100%'',
''height'': height ? height + ''px'': '''',
}).
selectAll(''circle'');
}
render(newValue) {
if (!newValue) return;
this.x = d3.scale.linear().domain([-10, 110]).range([0, 250]);
this.y = d3.scale.linear().domain([-10, 110]).range([100, 0]);
this.circles = this.circles
.data(newValue);
this.circles.exit().remove();
this.circles.enter()
.append(''circle'');
this.circles
.transition()
.attr("r", d => d.size ? d.size: this.defaultSize)
.style("fill", d => d.color)
.attr(''cx'', d => this.x(d.x))
.attr(''cy'', d => this.y(d.y));
}
onChange() {
this.render(this.data);
}
}