question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Re-render Component on Canvas when tagName has changed

See original GitHub issue

I’m trying to build a basic Header component that lets you select H1 to H6 with a trait. But when an option is selected, the canvas doesn’t update. The change is visible in the code view, and if I move the element in the canvas with the drag tool, the tag then changes. I have been reading the API docs as well as the source, but I can’t make the component automatically re-render. I suspect that Grapes is not listening for a change of the component tag name. What is the appropriate way to force a re-render in this case?

var comps = editor.DomComponents;
var blocks = editor.BlockManager;
var textType = comps.getType('text');
var textModel = textType.model;
var textView = textType.view;

comps.addType('header', {
  model: textModel.extend({
    defaults: Object.assign({}, textModel.prototype.defaults, {
      'custom-name': 'Header',
      tagName: 'h1',
      traits: [
        {
          type: 'select',
          options: [
            {value: 'h1', name: 'One (largest)'},
            {value: 'h2', name: 'Two '},
            {value: 'h3', name: 'Three '},
            {value: 'h4', name: 'Four '},
            {value: 'h5', name: 'Five '},
            {value: 'h6', name: 'Six (smallest)'},
          ],
          label: 'Size',
          name: 'header-size',
          changeProp: 1
        }
      ]
    }),

    init() {
      this.listenTo(this, 'change:header-size', this.changeTagName);
    },

    changeTagName() {
      // view.tagName is a fn that returns model.tagName
      this.set('tagName', this.get('header-size'));
    }

  }, {
    isComponent: function(el) {
      if(el && ['H1','H2','H3','H4','H5','H6'].includes(el.tagName)) {
        return {type: 'header'};
      }
    }
  }),
  view: textView
});

blocks.add('header', {
  label: 'Header',
  category: 'Basic',
  attributes: {class:'fa fa-header'},
  content: {
    type:'header',
    content:'Insert your header text here',
    activeOnRender: 1
  }
});

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
artfcommented, Dec 14, 2017

@z1lk I already added such a thing for the next release

// Model
// inside init
this.listenTo(this, 'change:tagName', this.tagUpdated);
// ...
tagUpdated() {
    const coll = this.collection;
    const at = coll.indexOf(this);
    coll.remove(this);
    coll.add(this, { at });
},
1reaction
z1lkcommented, Dec 20, 2017

I’m not sure why el would be a string, but see the commit that closed the issue: https://github.com/artf/grapesjs/commit/e450cb98855d16ad819f1214350825a50e45e910

If you’re using the latest Grapes version, the Component listens for a change of tagName and does the node replacement itself. So you should be able to remove your init and tagUpdated functions. The trait will update tagName and the Component will do the rest.

Edit:

Another thing I thought of is: sometimes the object passed to isComponent doesn’t have the method that I call on it, and there will be an error thrown in that case. You could do a safety check first:

if(el && el.tagName && ['H1','H2','H3','H4','H5','H6'].includes(el.tagName)) {
  ...
Read more comments on GitHub >

github_iconTop Results From Across the Web

Rerender component as mobx store is updated - Stack Overflow
I am using chart.js to show price changes from the backend in real time. Backend sends a new price when it is changed...
Read more >
HTML5 elements vanish when rerendering Visualforce
I have noticed that HTML 5 tags like <section> and <header> disappear from the page when I reRender the page. On initial load...
Read more >
React: Creating an Interactive Canvas Component - Medium
In this guide, we will take a look at how to set up a basic React.js application that incorporates an interactive HTML5 canvas...
Read more >
When does React re-render components? - Felix Gerschau
React re-render explained. React is known for providing a fast user experience by only updating the parts of the UI that have changed....
Read more >
Reusable react component with Canvas doesn't render ...
[Solved]-Reusable react component with Canvas doesn't render canvas with its props-Chart.js ... The issue was here, I will share here in case someone...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found