I can instantiate (sub)components manually using tags, but I don\'t know how to do it dynamically, or, how to insert and remove different components in the same area using t
Would like to upvote @martypdx's answer more than once. Inspired by his answer, I came up with something I'd like to share. It adds the following things:
Create multiple instances of a type of Component (Ractive.extend)
Component instances are alive and can receive messages from external listeners even if they have been unrendered.
Here is my fiddle: https://jsfiddle.net/vikikamath/z5otgzpL/9/
// Inspired by http://stackoverflow.com/a/31080919/405117
var mapper = {
'A': function(instanceId){
var handleAData;
return Ractive.extend({
template: 'I am A this is my data: {{#datas}}- {{.}}
{{/datas}}
',
data: {
datas:[]
},
onrender: function() {
handleAData = function(txt){
this.push('datas', txt);
}.bind(this);
r.on(instanceId, handleAData);
},
onunrender: function() {
r.off(instanceId, handleAData);
}
});
}
,'B': function(instanceId){
var handleBData;
return Ractive.extend({
template: 'I am B this is my data: {{#datas}}- {{.}}
{{/datas}}
',
data: {
datas:[]
},
onrender: function() {
handleBData = function(txt){
this.push('datas', txt);
}.bind(this);
r.on(instanceId, handleBData);
},
onunrender: function() {
r.off(instanceId, handleBData);
}
});
}
,'C': function(instanceId){
var handleCData;
return Ractive.extend({
template: 'I am C this is my data: {{#datas}}- {{.}}
{{/datas}}
',
data: {
datas:[]
},
onrender: function() {
handleCData = function(txt){
this.push('datas', txt);
}.bind(this);
r.on(instanceId, handleCData);
},
onunrender: function() {
r.off(instanceId, handleCData);
}
});
}
,'D': function(instanceId){
var handleDData;
return Ractive.extend({
template: 'I am D this is my data: {{#datas}}- {{.}}
{{/datas}}
',
data: {
datas:[]
},
onrender: function() {
handleDData = function(txt){
this.push('datas', txt);
}.bind(this);
r.on(instanceId, handleDData);
},
onunrender: function() {
r.off(instanceId, handleDData);
}
});
}
}
/* arbitrarily select a component */
function pickRandomComponent() {
return String.fromCharCode(Math.floor(Math.random() * Object.keys(mapper).length) + 65);
}
var DynamicComponent = Ractive.extend({
template: ' ',
components: {
component: function() {
return this.get('name');
}
},
oninit: function(){
this.observe('name', function(){
this.reset();
}, { init: false});
}
});
var r = new Ractive({
el: 'main',
template: '#template',
components: {
dummy: Ractive.extend({ template: 'Welcome message' }),
dynamic: DynamicComponent
},
data: {
foo: 'foo',
list: ['dummy'],
name: 'dummy',
textdata: ''
},
oninit: function() {
this.on("sendDataToCurrentComponent", function() {
r.fire(this.get('name'), this.get('textdata'))
}.bind(this));
this.on('addComponent', function(){
var rndComponent = pickRandomComponent();
var now = Date.now();
var componentInstanceName = rndComponent + '-' + now
this.components[componentInstanceName] = mapper[rndComponent](componentInstanceName)
this.push('list', componentInstanceName);
}.bind(this));
}
});