【问题标题】:Multiple instance of angular 4 directive called from a component mesed up the input values从组件调用的 angular 4 指令的多个实例弄乱了输入值
【发布时间】: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);

标签: javascript angular angular-directive angular-components


【解决方案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 中提供的。使用角度,同一根组件的服务提供者是单例的。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-20
        • 2018-02-07
        • 2023-03-14
        相关资源
        最近更新 更多