Issue #4851Opened January 17, 2023by chaegumi0 reactions

BUG: this.on('change:attributes:type', this.handleTypeChange) do not support array type

Question

GrapesJS version

  • I confirm to use the latest version of GrapesJS

What browser are you using?

Chrome 108.0.5359.125

Reproducible demo link

https://codesandbox.io/s/frosty-darkness-7po7xl

Describe the bug

How to reproduce the bug?

  1. use myBlock
  2. click test button

What is the expected behavior? this.on("change:list1", this.handleList1Change);
work every time

What is the current behavior? this.on("change:list1", this.handleList1Change); only run once

If is necessary to execute some code in order to reproduce the bug, paste it here below:

import grapesjs from "grapesjs";

const myPlugin = function (editor, opts) {
  editor.TraitManager.addType("listitem", {
    createInput({ trait }) {
      this.traitName = trait.get("name");
      this.items = [
        {
          id: 1,
          title: "Item1"
        }
      ];
      const el = document.createElement("div");

      el.innerHTML = '<button type="button">test</button>';

      el.querySelector("button").addEventListener("click", (ev) =>
        this.onChange(ev)
      );

      return el;
    },
    onEvent({ elInput, component, event }) {
      // console.log(event);

      const itemLength = this.items.length;

      this.items.push({
        id: itemLength,
        title: `Item${itemLength}`
      });

      component.set(this.traitName, this.items);
      console.log("onEvent", this.items);
    },
    onUpdate({ elInput, component }) {}
  });

  editor.DomComponents.addType("myComponent", {
    isComponent: (el) => {
      if (el && el.classList && el.classList.contains("widget1")) {
        return true;
      }
    },
    model: {
      defaults: {
        attributes: { class: "widget1" },
        components: `<div>test</div>`,
        traits: [
          {
            type: "listitem",
            name: "list1",
            label: "list1",
            changeProp: 1
          }
        ]
      },
      init() {
        this.on("change:list1", this.handleList1Change);
      },
      handleList1Change() {
        console.log("onChange", this.attributes.list1);
      }
    },
    view: {}
  });

  editor.BlockManager.add("myBlock", {
    label: "MyBlock",
    content: { type: "myComponent" },
    select: true
  });
};

const editor = grapesjs.init({
  container: "#gjs",
  fromElement: 1,
  storageManager: { type: 0 },
  plugins: [myPlugin]
});

editor.on("component:selected", function (component) {
  editor.Panels.getButton("views", "open-tm").set({ active: true });
});

image

Code of Conduct

  • I agree to follow this project's Code of Conduct

Answers (2)

artfJanuary 18, 20230 reactions

Listeners don't see deep changes so you have to create a new array in that case

component.set(this.traitName, [...this.items]);
chaegumiJanuary 18, 20230 reactions

Thanks @artf. I use JSON.stringify and JSON.parse to deal my data.

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.