Tengo un componente en angular 4 que se llama tres veces. En los metadatos de la plantilla, tengo un div con una directiva con algunos enlaces como este.
@import {gServ} from '../gServ.service'; @Component: ({ selector: 'sr-comp', template: `<div gDirective [cOptions]="dataChart">` }) export class SGComponent implements OnInit { @Input('report') public report: IReportInstance; cOptions:any; constructor(private gServ: gServ) { } ngOnInit(){ this.cOptions = {}; this.cOptions = this.gServ.objectMerge(this.gServ.defaultOpt, this.report.opt); //this.report.opt is binded to a component when is instantiated. //this.gServ.objectMerge is a function that merge the two objects } }this.cOptions cambia para cada instancia del componente, luego en la directiva tengo esto:
import { Directive, ElementRef, HostListener, Input, OnInit } from '@angular/core'; @Directive({ selector: '[gDirective]' }) export class SGDirective implements OnInit { public _element: any; @Input() public cOptions: string; constructor(public element: ElementRef) { this._element = this.element.nativeElement; } ngOnInit() { console.log(this.cOptions); } } El problema es que console.log(this.cOptions); siempre imprime el mismo objeto, incluso cuando el componente establece cOptions con diferentes valores en el método ngOnInit del componente.
¿Tienes alguna idea de lo que está mal?
El enlace de propiedad de su componente [cOptions]="dataChart" no se ve bien, por lo que su dataChart ni siquiera está definido. debería ser como [DIRECTIVE_PROPERTY]="COMPONENT_PROPERTY" y su COMPONENT_PROPERTY ni siquiera está definida en la clase de componente SGComponent .
Su clase de componente debería ser algo como esto:
@import {gServ} from '../gServ.service'; @Component: ({ selector: 'sr-comp', template: `<div gDirective [cOptions]="Options">` }) export class SGComponent implements OnInit { @Input('report') public report: IReportInstance; Options:any; constructor(private gServ: gServ) { } ngOnInit(){ this.Options = {}; this.Options = this.gServ.objectMerge(this.gServ.defaultOpt, this.report.opt); } }@Ashwani señala un problema válido con su código. La forma en que su plantilla está conectando las cosas, nunca se pasará nada a la entrada SGDirective .
Otro problema potencial con el que te podrías encontrar tiene que ver con el código de gServ . Si gServ es un singleton (que probablemente sea el caso) y devuelve el mismo objeto a cada uno de los SGComponent s, entonces todos los SGDirective s tendrán el mismo valor. Una forma sencilla de probar esto es poner {{Options | json}} en la plantilla SGComponent .
Para crear una nueva instancia del servicio gServ para cada SGComponent , puede agregar una matriz de providers a los metadatos de @Component . Se vería así:
import {gServ} from '../gServ.service'; @Component({ selector: 'sr-comp', template: `{{Options | json}}<div gDirective [cOptions]="Options"></div>` providers: [gServ], }) export class SGComponent implements OnInit { @Input('report') public report: IReportInstance; Options:any; constructor(private gServ: gServ) { } ngOnInit(){ this.Options = this.gServ.objectMerge(this.gServ.defaultOpt, this.report.opt); } }Probablemente tenga el mismo retorno/valor en this.gServ.objectMerge) (puede probarlo sin llamar al servicio y pasar cada uno de los objetos creados por usted)
@import {gServ} from '../gServ.service'; @Component: ({ selector: 'sr-comp', template: `<div gDirective [cOptions]="dataChart">` }) export class SGComponent implements OnInit { //@Input('report') public report: IReportInstance; cOptions:any; constructor(private gServ: gServ) { } ngOnInit(){ this.cOptions = {nicolas: 'nicolas1'}; //change this in the next component that use the directive } }Si ese es el caso, su problema es que gServ se proporciona en el mismo rootComponent. con angular, el proveedor de servicios en el mismo rootComponent es singleton.
¡Y use el mismo tipo en su directiva y su componente!