组件的构造函数被调用两次

时间:2019-07-24 13:53:46

标签: angular typescript constructor angular6 jsplumb

所以我有这个子组件,其中id属性是随机设置的:

export class FileSelectionComponent implements AfterViewInit {
  public type = 'app-file-selection';
  public id = 'FileSelection#' + Math.random().toString(16).slice(2, 8);
  @Input() jspinst: any;
  public x;
  public y;
  public selected_file: string;

  constructor(public dialog: MatDialog, private httpClient: HttpClient) {
    this.selected_file = '';
    console.log('constructor called');
    console.log(this.id);
  }
  ngAfterViewInit() {
    ...
    this.jspinst.addEndpoint(this.id, { anchor: 'Right'}, Endpoint1);
    this.jspinst.addEndpoint(this.id, { anchor: 'Left'}, Endpoint2);
    this.jspinst.draggable(this.id);
  }
}

,父组件如下所示:

export class FlowComponent implements OnInit, AfterViewInit, OnChanges {
 public nodes: Array<any>;
 public jspl;

  constructor() {
    this.nodes = [];
    this.jspl = jsPlumb.getInstance();
  }

  addNode(type) {
        let nn = new FileSelectionComponent();
        this.nodes = this.nodes.concat([nn]);
        s = this.nodes;
        console.log('object created and added');
  }

  ngAfterViewInit() {
    s = this.nodes;
    this.jspl.bind('connection', function (info) {
      console.log(info.sourceId+' ----> '+info.targetId); //this output
      console.log(s[0].id+' ----> '+s[1].id); // and this output are not the same while they should
      console.log(Object.keys(s[0]));
      console.log(Object.values(s[0]));
    });
  }
}

当我单击按钮时,将调用addNode方法,并且您可以猜测FileSelectionComponent的构造函数被调用了两次,生成了两个不同的ID,这使我无法检索到相关的触发connection事件时的节点。 我发现了类似的问题,例如this one,但没有一个帮助

  1. 我的按钮上有一个type="button"
  2. 我没有引导父组件和子组件,实际上我没有引导任何组件,我已经检查了app.module.ts(我什至不知道引导是关于)。
  3. 我没有忘记关闭主机组件中的选择器标签。
  4. 我的代码中没有platformBrowserDynamic().bootstrapModule(AppModule);
  5. 编译器未显示任何错误消息。

父级模板如下:

<div id="cont">
  <div *ngFor="let n of nodes">
    <app-file-selection [jspinst]="jspl" *ngIf="n.type === 'app-file-selection'"></app-file-selection>
  </div>
</div>
  <button type="button" mat-icon-button matTooltip="Files selection" (click)="addNode('file-selection')"><mat-icon aria-label="Side nav toggle icon">insert_drive_file</mat-icon></button>

我知道这种问题一遍又一遍地问,但是我的搜索似乎没有帮助,谢谢。

编辑 我已经尝试过将该随机分配放置在构造函数中(导致两个id,一个被jsplumb捕获,一个由父组件接收),然后将其放置在OnInit中(仅产生一个id,但父组件不知道)。 / p>

2 个答案:

答案 0 :(得分:0)

您可以使用局部变量“ let i = index”来获取* ngFor数组的索引(在您的情况下为nodes)。然后使用(单击)返回,将逻辑写入您的parent.component.ts文件中。

<div *ngFor="let n of nodes; let i = index">
  <<app-file-selection (click)="addNode(i)></<app-file-selection>
</div>

答案 1 :(得分:0)

您的fasta标记已默认实例化该组件。这意味着它会在您的模板和逻辑中得到实例化。一般来说,您不需要使用带有角度分量的New。

您可以尝试以下操作:

<app-file-selection></app-file-selection>
this.nodes = new BehaviorSubject<Array<any>>([]);
this.fileSelectorNodes = [];

ngOnInit() {
  this.nodes.subscribe(nodes => {
    this.updateNodes(nodes);
  });
}

addNode(type) {
  const nodes = this.nodes.getValue();
  nodes.push(type);
  this.nodes.next(nodes);
}

updateNodes(nodes: Array<any>) {
  this.fileSelectorNodes = nodes.filter(node => node === 'app-file-selection');
}