Issue #2329Opened October 15, 2019by mustahsanmustafa1 reactions

[HELP] Canvas clears component rendering after Traits value change event

Question

I have created custom components and blocks, but when value of traits change, the rendered element gets invisible from the canvas until it is reloaded.

const DynamicBodyComponent = editor => {
    editor.DomComponents.addType('app-body', {
        isComponent: el => el.tagName === 'app-body',
        view: {
            onRender() { 		// use onRender hook instead of render
                const el = document.createElement("div");
                el.innerHTML = `
<div>Dynamic Page Content Placeholder (Page Specific Content Will be displayed here..)</div>
<style>
 </style>`;
                this.el.appendChild(el);
            }
        },
        model: {
            defaults: {
                editable: true,
                droppable: true,
                traits: [
                    // Strings are automatically converted to text types
                    {type: 'text', name: 'searchPlaceHolder', label: 'Search Text'}
                ],
                attributes: {
                    'searchPlaceHolder': 'Search Over 1000 Scrimming Good Deals'
                }
                // As by default, traits are binded to attributes, so to define
                // their initial value we can use attributes
            },
            init() {
                this.listenTo(this, 'change:attributes', this.handleChange);
                this.handleChange();
            },
            handleChange() {
                const value = JSON.stringify(this.getAttributes());
                this.components(`<app-body props='${value}'></app-body>`); //this line is causing issue
            },
        }
    });

    editor.BlockManager.add('app-body', {
        label: 'Dynamic Page Body',
        attributes: {
            class: 'fa fa-file-code-o'
        },
        category:{
            label: "Theme",
            order: 1
        },
        content: {
            type: 'app-body'
        }
    });
}

So whenever this.components(`<app-body props='${value}'></app-body>`); this line is executed, the loaded block gets invisible or unrendered. A workaround that i got was to re-render DomComponents after this call: editor.DomComponents.render() but that does not seems a good approach, So is there anyother workaround for this problem?

Answers (2)

artfOctober 19, 20191 reactions

@mustahsanmustafa I think there is something wring here...

init() {
                this.listenTo(this, 'change:attributes', this.handleChange);
                this.handleChange();
            },
            handleChange() {
                const value = JSON.stringify(this.getAttributes());
                this.components(`<app-body props='${value}'></app-body>`); //this line is causing issue
            },

For any new app-body component you're creating a new inside with this this.components('<app-body props='${value}'></app-body>'). The method this.components updates inner content not the component itself... If you need to update a property you should do just this this.set('propName', 'propValue'). You can also listen a single attribute change if you want:

this.listenTo(this, 'change:attributes:search-placeholder', this.handleChange);

ps. By HTML5 specs attribute names SHOULD ONLY be in lower case, so change searchPlaceHolder in something like search-placeholder

pouyamiralayiOctober 16, 20190 reactions

Hi there! being more specific in reaction to what attribute is actually changing would help you to reduce the performance issue in your case. cheers!

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.