从组件调用的 angular 4 指令的多个实例弄乱了输入值

Posted

技术标签:

【中文标题】从组件调用的 angular 4 指令的多个实例弄乱了输入值【英文标题】:Multiple instance of angular 4 directive called from a component mesed up the input values 【发布时间】:2017-09-23 02:04:23 【问题描述】:

我在 Angular 4 中有一个组件,它被调用了 3 次。在模板元数据中,我有一个带有指令的 div,其中包含一些类似这样的绑定。

@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 为组件的每个实例更改,然后在指令中我有这个:

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);
  

问题在于console.log(this.cOptions); 总是打印同一个对象,即使组件在组件的ngOnInit 方法中设置了具有不同值的cOptions

你知道出了什么问题吗?

【问题讨论】:

我有类似的问题。 你有没有直接尝试console.log 服务的结果,在你的组件ngOnInitthis.cOptions = this.gServ.objectMerge(...); console.log(this.cOptions); 【参考方案1】:

您的组件属性绑定[cOptions]="dataChart" 看起来不太好,甚至没有定义您的dataChart 的原因。它应该像 [DIRECTIVE_PROPERTY]="COMPONENT_PROPERTY" 而你的 COMPONENT_PROPERTY 甚至没有在 SGComponent 组件类中定义。

你的组件类应该是这样的:

@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);
    
 

【讨论】:

【参考方案2】:

@Ashwani 指出您的代码存在一个有效问题。您的模板连接事物的方式是,不会将任何内容传递给SGDirective 输入。

您可能遇到的另一个潜在问题与gServ 代码有关。如果gServ 是一个单例(可能就是这种情况)并且它向每个SGComponents 返回相同的对象,那么所有SGDirectives 将具有相同的值。一个简单的测试方法是将Options | json 放入SGComponent 模板中。

要为每个SGComponent 创建gServ 服务的新实例,您可以将providers 数组添加到@Component 元数据。它看起来像这样:

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);
    

【讨论】:

【参考方案3】:

您在this.gServ.objectMerge) 处可能具有相同的返回/值(您可以在不调用服务的情况下对其进行测试,并传递您制作的每个不同的对象)

@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

    

如果是这种情况,您的问题是 gServ 是在同一个 rootComponent 中提供的。使用角度,同一根组件的服务提供者是单例的。

并且在你的指令和你的组件中使用相同的类型!!

【讨论】:

以上是关于从组件调用的 angular 4 指令的多个实例弄乱了输入值的主要内容,如果未能解决你的问题,请参考以下文章

具有多个子组件实例的Angular2父组件

如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件

Angular 在父子组件中使用多个服务实例

Angular如何将数据从指令传递到父组件

如何使用多个选择器定义 Angular 2 组件或指令

Angular - 使用自定义指令加载多个组件返回未定义