gridstack / gridstack.js

Build interactive dashboards in minutes.
https://gridstackjs.com
MIT License
6.69k stars 1.28k forks source link

[Angular] Can't add widget component #2651

Closed nguyenthanhtien closed 6 months ago

nguyenthanhtien commented 6 months ago

Subject of the issue

I'm using gridstack in our project, but when i trying add widget component to items, it's not show. Is it bug? Any otherway we can workaround? Also dont see any resize button each widget. image

gdp-macro.component.html

div>
  <div class="flex justify-content-between align-items-center flex-grow-1">
    <div class="view-actions flex flex-wrap align-items-center gap-2 ml-auto">
      <p-button
        (onClick)="add()"
        type="submit"
        label="ADD WIDGET"
        styleClass="p-button-ssm" />
    </div>
  </div>
  <!-- <div class="grid-stack"></div> -->
  <gridstack
    class="grid-stack"
    (changeCB)="onChange($event)"
    (resizeStopCB)="onResizeStop($event)"
    [options]="gridOptions">
    <gridstack-item
      *ngFor="let n of items; trackBy: identify"
      [options]="n">
      <div>Index {{n.id}}</div>
      <div class="grid-stack-item-content" [innerHTML]="n.content"></div>
    </gridstack-item>
  </gridstack>
</div>

gdp-macro.component.ts

import { Component, OnInit } from '@angular/core';
import { GridStack, GridStackWidget } from 'gridstack';
import { elementCB, GridstackComponent, NgGridStackOptions, NgGridStackWidget, nodesCB } from 'gridstack/dist/angular';

import { EconomicSummaryComponent } from '../../components/economic-summary/economic-summary.component';
import { IssuerRatingComponent } from '../../components/issuer-rating/issuer-rating.component';
import { ReportMacroComponent } from '../../components/report-macro/report-macro.component';
@Component({
  selector: 'app-gdp-macro',
  templateUrl: './gdp-macro.component.html',
  styleUrls: ['./gdp-macro.component.scss']
})
export class GdpMacroComponent implements OnInit{
  index = 0;
  private grid!: GridStack;

  public items: NgGridStackWidget[] = [
    // { x: 0, y: 0, id: '1' },
    // { x: 0, y: 1, id: '2' },
    // { x: 1, y: 1, id: '3' },
  ];

  public gridOptions: NgGridStackOptions = {
    column: 2,
    cellHeight: 200,
    acceptWidgets: true,
    children: this.items
  };

  constructor() {
    GridstackComponent.addComponentToSelectorType([EconomicSummaryComponent,
      IssuerRatingComponent,
      ReportMacroComponent]);
  }

  ngOnInit(): void {
    this.grid = GridStack.init(this.gridOptions).load(this.items);
  }

  public onChange(data: nodesCB) {
    console.log('change ', data.nodes.length > 1 ? data.nodes : data.nodes[0]);
    console.log('all nodes ', data.nodes);
  }

  public onResizeStop(data: elementCB) {
    console.log('resizestop ', data.el.gridstackNode);
  }

  public identify(index: number, w: GridStackWidget) {
    return w.id; // or use index if no id is set and you only modify at the end...
  }

  public add() {
    this.items.push({ x: this.index, id: this.index.toString(), selector: 'app-economic-summary' });
    this.index++;
    console.log('all nodes ', this.items);
  }

  public delete() {
  }

  public modify() {
  }
}

Your environment

Steps to reproduce

You MUST provide a working demo - keep it simple and avoid frameworks as that could have issues - you can use https://jsfiddle.net/adumesny/jqhkry7g

Expected behavior

Tell us what should happen. If hard to describe, attach a video as well.

adumesny commented 6 months ago

Not a bug. angualr does not detect changes to a list, you must provide a new list for ng to detect it, and not push to it. In this case I woudl jsut call grid.load(items) instead and GS + your callbacks will handle it.

don't forget to donate if you find this lib useful!