tiberiuzuld / angular-gridster2

Angular gridster 2
https://tiberiuzuld.github.io/angular-gridster2
MIT License
1.27k stars 377 forks source link

Gridster does not update view if the array of gridsteritems is empty at the beginning #679

Open ArkasDev opened 3 years ago

ArkasDev commented 3 years ago

In relation to this issue #560 I have implemented the following workaround. Now the following problem occurs. The solution does not work if there is no item in the array at the beginning. If I add a new item, the observable is triggered and fills the array, but Gridster is not updated. As soon as an item exists in the array at the beginning and I add new items afterwards, Gridster updates and shows the new item.

If I remove the changeDetection: ChangeDetectionStrategy.OnPush this problem does not occur, but then all newly added items are placed on top of each other at position (0,0), which is also not useful.

@Component({
  templateUrl:
  `
  <gridster [options]="config">
    <gridster-item class="gridster-item" [item]="widget" *ngFor="let widget of widgets; trackBy: trackByWidgetId">
      // content
    </gridster-item>
  </gridster>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DeviceExplorerDashboardGridsterComponent implements OnInit, OnDestroy {

  @Select(DeviceDashboardConfigState.getCurrentDeviceDashboard)
  public widgets: Array<GridsterItem> = [];

  public widgets$: Observable<Array<GridsterItem>>;

  public ngOnInit(): void {
    this.widgets$
      .pipe(distinctUntilChanged((p: any, q: any) => JSON.stringify(p) === JSON.stringify(q)))
      .subscribe((widgets: GridsterItem[]) => {
        this.widgets = [...widgets];
      });
  }

  public trackByWidgetId(index: number, widget: any): string {
    return widget.id;
  }
}
ArkasDev commented 3 years ago

Another workaround to solve this issue:

constructor(private ref: ChangeDetectorRef ) {}

...

this.widgets$
      .pipe(distinctUntilChanged((p: any, q: any) => JSON.stringify(p) === JSON.stringify(q)))
      .subscribe((widgets: GridsterItem[]) => {
        if(this.widgets.length === 0 && widgets.length === 1) {
          this.widgets = [];
          this.widgets.push(widgets[0])
          this.ref.markForCheck();
          return;
        }
        this.widgets = [...widgets];
      });