网站搜索

javascript - 如何在 Angular 中点击按钮时更改 gridster2 的选项值


这是代码和输出:https://stackblitz.com/edit/d3-angular-gridster2-working-axhc7u?file=src%2Fapp%2Fgrid%2Fgrid.component.html

网格-HTML :

<gridster [options]="options">
  <gridster-item [item]="item" *ngFor="let item of dashboard">
   
  </gridster-item>
</gridster>

GRID-TS :

ngOnInit() {
  @Input() editing: any;
    this.options = {
      gridType: GridType.Fit,
      displayGrid: DisplayGrid.Always,
      enableEmptyCellClick: false,
      enableEmptyCellContextMenu: false,
      enableEmptyCellDrop: false,
      enableEmptyCellDrag: false,
      enableOccupiedCellDrop: false,
      emptyCellClickCallback: this.emptyCellClick.bind(this),
      emptyCellContextMenuCallback: this.emptyCellClick.bind(this),
      emptyCellDropCallback: this.emptyCellClick.bind(this),
      emptyCellDragCallback: this.emptyCellClick.bind(this),
      emptyCellDragMaxCols: 50,
      emptyCellDragMaxRows: 50
    };

    this.dashboard = [
      { cols: 2, rows: 1, y: 0, x: 0 },
      { cols: 2, rows: 2, y: 0, x: 2 },
      { cols: 1, rows: 1, y: 0, x: 4 },
      { cols: 3, rows: 2, y: 1, x: 4 },
      { cols: 1, rows: 1, y: 4, x: 5 },
      { cols: 1, rows: 1, y: 2, x: 1 },
      { cols: 2, rows: 2, y: 5, x: 5 },
      { cols: 2, rows: 2, y: 3, x: 2 },
      { cols: 2, rows: 1, y: 2, x: 2 },
      { cols: 1, rows: 1, y: 3, x: 4 },
      { cols: 1, rows: 1, y: 0, x: 6 }
    ];
  }

我在这里尝试做的是启用 enableEmptyCellDrag。例如,我点击了编辑按钮,然后 edit 的值是 true,然后 enableEmptyCellDrag 的值为 true。

我已经尝试过这个了:

ngOnChanges() {
 ///this.options['enableEmptyCellDrag'] = true // the enableEmptyCellDrag is undefined
 ///if (this.editing) {
 /// this.options['enableEmptyCellDrag'] = true // the value of enableEmptyCellDrag is change to true, but when I try to drag from the empty cell it doesn't work
 ///}

}

答案#1

如果我理解正确,你想将 this.options['enableEmptyCellDrag'] 设置为 @Input() editing 的值。

而你想让 gridster2(我必须承认我不知道这是什么)识别这个变化。

所以你有两个问题:

  1. 当你在 ngOnChanges 中时,直接访问你的 @Input() 会给你“旧的”值。

  2. 通常,为了让 Angular 检测对象的变化,你需要更改对象的引用。

所以你的 ngOnChanges 应该是这样的。

  ngOnChanges(changes: SimpleChanges) {
    if (changes.editing && changes.editing.currentValue) {
      // Solve problem 1)
      const newValueOfEditingInput = changes.editing.currentValue;

      // Solve Problem 2) - Create a new reference for this.options, so that angular (grister2) can detect the change
      this.options = {
        ...this.options,
        enableEmptyCellDrag: newValueOfEditingInput
      };
    }
  }

当然我没有测试过这个,但我希望它能帮到你

答案#2

依我看,我找到了一个更优雅的解决方案。

GridsterConfig 对象有一个 api.optionsChanged 子对象,它是一个函数。如果你运行它,这也会告诉 Gridster 选项已更改,而无需本质上重新实例化对象(无论如何这可能只会运行该函数)。看起来更安全,也更优雅。

因此,你的 on change 现在可以看起来像这样:

  ngOnChanges(changes: SimpleChanges) {
    if (changes.editing && changes.editing.currentValue) {
      this.options.enableEmptyCellDrag = changes.editing.currentValue;
      this.options.api.optionsChanged();
    }
  }

我还建议创建一个类似如下的类,这将防止你被迫去检查这些选项是否存在(if语句只是检查GridsterConfig接口的可选选项是否已定义……所以如果你提前定义了它们,就不需要这样做……不确定为什么Gridster会让它们是可选的……依我看,这些选项应该总是存在,但可以设置为null或默认值)。

export class DashboardOptions implements GridsterConfig{
  gridType = GridType.Fit;
  compactType = CompactType.None;
  margin = 10;
  outerMargin = false;
  outerMarginTop = null;
  outerMarginRight = null;
  outerMarginBottom = null;
  outerMarginLeft = null;
  useTransformPositioning = true;
  mobileBreakpoint = 720;
  minCols = 1;
  maxCols = 100;
  minRows = 1;
  maxRows = 100;
  maxItemCols = 100;
  minItemCols = 1;
  maxItemRows = 100;
  minItemRows = 1;
  maxItemArea = 2500;
  minItemArea = 1;
  defaultItemCols = 1;
  defaultItemRows = 1;
  fixedColWidth = 105;
  fixedRowHeight = 105;
  keepFixedHeightInMobile = false;
  keepFixedWidthInMobile = false;
  scrollSensitivity = 10;
  scrollSpeed = 20;
  enableEmptyCellClick = false;
  enableEmptyCellContextMenu = false;
  enableEmptyCellDrop = false;
  enableEmptyCellDrag = false;
  enableOccupiedCellDrop = false;
  emptyCellDragMaxCols = 50;
  emptyCellDragMaxRows = 50;
  ignoreMarginInRow = false;
  public draggable = {
    enabled: false,
    delayStart: 200,
    start: () => {},
    stop: () => {}
  };
  public resizable = {
    enabled: true,
    delayStart: 200,
    start: () => {},
    stop: () => {}
  };
  swap = false;
  pushItems = true;
  disablePushOnDrag = false;
  disablePushOnResize = false;
  pushDirections = {north: true, east: true, south: true, west: true};
  pushResizeItems = false;
  displayGrid = DisplayGrid.Always;
  disableWindowResize = false;
  disableWarnings = false;
  scrollToNewItems = false;
  api = {
    resize: () => {},
    optionsChanged: () => {},
  };
  itemChangeCallback = (item: GridsterItem, itemComponent: GridsterItemComponentInterface) => {};
}

那么,你的 on change 现在可以看起来像这样:

  ngOnChanges(changes: SimpleChanges) {
      this.options.enableEmptyCellDrag = changes.editing.currentValue;
      this.options.api.optionsChanged();
  }