konvajs / ng2-konva

Angular & Canvas - JavaScript library for drawing complex canvas graphics using Angular.
http://rafaelescala.com/ng2-konva/
119 stars 33 forks source link

How to change and update the created list in an HTML template? #27

Open Vasily-van-Zaam opened 5 years ago

Vasily-van-Zaam commented 5 years ago

Hello. I created in html-template list

<ko-group *ngFor="let item of listItems" [config]="item.getConfigGroup()" (click)="handleClick($event)">
  <ko-image [config]="item.getConfigImage()"></ko-image>
  <ko-line [config]="item.getConfigAix()"></ko-line>
</ko-group>

In the list I can change the configs, but I can not increase the list or decrease. The list in the code grows, but not on the canvas

ap1969 commented 4 years ago

Can I give this is a kick please? Same problem - the ko-image doesn't seem to actually render an image.

Could you (the project owner) provide an example of how to have an array of Image configs, and have them render on-screen please?

Regards, Andy

lszabados commented 4 years ago

HI, Although this was a problem for me, the list does not update automatically.

To resolve this issue, modify the ngAfterContentInit function in the stage.component.ts and core-shape.component.ts files.

The following code solves the problem, but each time you change it, it deletes all the nodes and then re-creates them.

ngAfterContentInit() {
    this.shapes.forEach((item: CoreShape) => {
      this._stage.add(item.getStage());
      updatePicture(this._stage);
    });

    // subscribe changes
    this.shapes.changes.subscribe(() =>{
      const stage = this.getStage();
      if (stage) {
        // old nodes
        const nodes = this._stage.getChildren();

        // remove all nodes...
        nodes.forEach(node => {
          node.remove();
          node.destroy();
        });

        // create all nodes
        this.shapes.forEach((item: CoreShape) => {
          this._stage.add(item.getStage());
          updatePicture(this._stage);
        });
      }
    });
  }

I use the code below, here it only removes deleted items and creates new ones.

ngAfterContentInit() {
    this.shapes.forEach((item: CoreShape) => {
      this._stage.add(item.getStage());
      updatePicture(this._stage);
    });

    // subscribe changes
    this.shapes.changes.subscribe(() =>{
      const stage = this.getStage();
      if (stage) {
        const nodes = this._stage.getChildren();
        // filter deleted  items
        const snodes = nodes.filter(node => !this.shapes.some(s => s.getStage()._id === node._id));
        snodes.forEach(node => {
          node.remove();
          node.destroy();
        });

        // filter new items
        const sh = this.shapes.filter(s => !nodes.some(n => n._id === s.getStage()._id));
        sh.forEach((item: CoreShape) => {
          this._stage.add(item.getStage());
          updatePicture(this._stage);
        });
      }
    });
  }

If we move a shape between two layers, we use the moveTo function before modifying the Observable array. This is important so that the remove and add parts do not run in this case!