[QUESTION] Reinit model's components function
Question
Hello guys,
I have a custom component with different structure based on prop's value. How can i recall/reinit model's components function on prop change event.
const EDC = editor.DomComponents;
const TableType = EDC.getType('table'),
TableModel = TableType.model,
TableView = TableType.view;
EDC.addType('product', {
isComponent: (el) => 'product' in el.dataset,
model : TableModel.extend({
defaults: {
...TableModel.prototype.defaults,
attributes : {
width : '100%',
border : 0,
cellspacing : 0,
cellpadding : 0,
'data-product': '',
},
arrangement: 'v',
traits : [
{
type : 'select',
name : 'arrangement',
label : 'Arrangement',
changeProp: 1,
options : [
{
value: 'h',
label: 'Horizontal',
},
{
value: 'hi',
label: 'Horizontal inverse',
},
{
value: 'v',
label: 'Vertical',
},
],
},
],
components : model =>
{
const arrangement = model.get('arrangement') || 'v';
let pBody;
if (arrangement === 'v')
{
pBody = [
_wrapComp('row', pImg, commonProps),
_wrapComp('row', pInfo, commonProps),
];
}
else
{
pImg.style['width'] = '200px';
const comps = arrangement === 'h'
? [pImg, pInfo]
: [pInfo, pImg];
pBody = [
_wrapComp('row', comps, commonProps),
];
}
return {
type : 'tbody',
components: pBody,
...commonProps,
};
},
},
}),
view : TableView.extend({
onRender()
{
const pItem = this.model.get('product') || {};
const pInfo = {
img : pItem.image || require('~/assets/img/product-ph/select-t.png'),
name : pItem.name || 'Product name',
price: pItem.price || '00.00',
url : pItem.url || url.front,
};
this.model.onAll((m) =>
{
const v = m.getView();
const vm = v.model;
switch (vm.get('uid'))
{
case 'url':
v.setAttribute('href', pInfo.url);
break;
case 'img':
v.setAttribute('src', pInfo.img);
break;
case 'name':
vm.set('content', pInfo.name);
break;
case 'price':
vm.set('content', pInfo.price);
break;
}
});
},
}),
});
Thank you in advance.
Answers (2)
I think this.components(this) will throw the Maximum call stack size exceeded error as you're trying to append the component to itself.
Probably you have to try this
this.components(
this.__proto__.defaults.components(this)
)
I'd probably suggest, in this case, to isolate the function to make things more cleaner
const createComponents = (model) => ...
EDC.addType('product', {
....
defaults: {
...
components: createComponents,
}
...
this.listenTo(this, 'change:propName', () =>
this.components(createComponents(this))
)
Hi @V1cu you can register your listeners inside the init hook like below:
model: {
init() {
this.listenTo(this, 'change:propName', () => this.components(this))
},
}
Cheers!
Related Questions and Answers
Continue research with similar issue discussions.
Issue #2549
[QUESTION] Update component view on property change
Hi everyone, I'm trying to create a component that will update it's view based on a property value My approach is bassed on #1227 and on th...
Issue #2329
[HELP] Canvas clears component rendering after Traits value change event
I have created custom components and blocks, but when value of traits change, the rendered element gets invisible from the canvas until it...
Issue #1341
[Question] How to work with Custom Components
Hello, I have some questions and issues about and with the grapes editorProblem 1 In a component, which class is there extended? Is it real...
Issue #2350
[Question] How do I add elements/sectors to views container using a custom button in the Panel
I have added a custom button to the Panel as below: const pm = editor.Panels; pm.addButton('views', { id: 'customButton', className: '', co...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.