so far I really love BlazeComponents. Now I just stumbled about a UseCase that is givin me a little headache.
This is what I’d like to achieve:
have 1 single MotherComponent (with an own template)
the MotherComponent shall own & manage several mixin-instances.
each if the mixin-instances shall be bound to a common MixinTemplate, but manage it’s own state.
In order to demo this UseCase I created a little game-code-snippet (see below). Your goal is to consume more than 2 foods and 2 beers.
Unfortunatly the code NOT work - it seems like right now each Mixin (FoodCounterMixin & BeerCounterMixin) has it’s data-context and the MotherComponent can NOT access it.
Does anyone have an idea how to get this to work? @mitar: How would you approach this?
This is the JS (scroll to see it all):
// ===================
// COUNTER Super-Mixin
class CounterSuperMixin extends BlazeComponent {
// COMMON template for Mixins
template() { return 'CounterSuperMixinTemplate'; }
constructor(settings) {
super();
var self = this;
self.title = settings.title;
self.counter = ReactiveField(0);
}
events() {
return super.events().concat({
'click': this.onClick,
});
}
onClick(event) {
var self = this;
self.counter(self.counter() + 1);
}
}
// FOOD Counter
class FoodCounterMixin extends CounterSuperMixin {
constructor() {
super(
{title: 'Food'}
);
}
}
FoodCounterMixin.register('FoodCounterMixin');
// BEER Counter
class BeerCounterMixin extends CounterSuperMixin {
constructor() {
super(
{title: 'Beer'}
);
}
}
BeerCounterMixin.register('BeerCounterMixin');
// ===================
// MOTHER-Component that holds all mixins
// and has access to its instances
// to regulate interactive behaviour
class MotherComponent extends BlazeComponent {
template() { return 'MotherComponentTemplate'; }
mixins() {
return [
new FoodCounterMixin(),
new BeerCounterMixin(),
];
}
success() {
var self = this;
if ( self.getMixin(FoodCounterMixin).counter() > 2
&& self.getMixin(BeerCounterMixin).counter() > 2) {
return true;
} else {
return false;
}
}
globalCounter() {
var self = this;
return self.getMixin(FoodCounterMixin).counter() + self.getMixin(BeerCounterMixin).counter();
}
}
MotherComponent.register('MotherComponent');
HTML (scroll to see it all);
<head>
<title>blaze components</title>
</head>
<body>
<p>Home</p>
{{> MotherComponentTemplate}}
</body>
<template name="MotherComponentTemplate">
<h1>MotherComponent {{motherValue}}</h1>
<p>Your aim for the night is to buy more than 2 foods and 2 beers!</p>
{{> FoodCounterMixin}} <!-- This is where the problem seems to be: the mixins are run in their own data-context -->
{{> BeerCounterMixin}}
<p>Global Counter: {{globalCounter}}</p>
{{#if success}}
<p>YIHAA, YOU SUCCESSFULLY BOUGHT ALL INGREDIENTS!</p>
{{/if}}
</template>
<template name="CounterSuperMixinTemplate">
<h1>{{title}}-Counter</h1>
<button>click me to count a {{title}}</button>
<p>{{title}}-counts: {{counter}}</p>
</template>
You never include a {{> FoodCounterMixin}}. This means that you are using a mixin as a component. Then you have in fact used the class twice and created two difference instances of the class, one inside the mixins(), and another when you did {{> FoodCounterMixin}}.
You probably want (and you should rename all Mixins to components, because you are really using them as components, but I am leave it so that it is clearer from your example and HTML.
// ===================
// COUNTER Super-Mixin
class CounterSuperMixin extends BlazeComponent {
// COMMON template for Mixins
template() { return 'CounterSuperMixinTemplate'; }
constructor(settings) {
super();
var self = this;
self.title = settings.title;
self.counter = ReactiveField(0);
}
events() {
return super.events().concat({
'click': this.onClick,
});
}
onClick(event) {
var self = this;
self.counter(self.counter() + 1);
}
}
// FOOD Counter
class FoodCounterMixin extends CounterSuperMixin {
constructor() {
super(
{title: 'Food'}
);
}
}
FoodCounterMixin.register('FoodCounterMixin');
// BEER Counter
class BeerCounterMixin extends CounterSuperMixin {
constructor() {
super(
{title: 'Beer'}
);
}
}
BeerCounterMixin.register('BeerCounterMixin');
// ===================
// MOTHER-Component that holds all mixins
// and has access to its instances
// to regulate interactive behaviour
class MotherComponent extends BlazeComponent {
template() { return 'MotherComponentTemplate'; }
success() {
var self = this;
if ( self.childComponents(FoodCounterMixin)[0].counter() > 2
&& self.childComponents(BeerCounterMixin)[0].counter() > 2) {
return true;
} else {
return false;
}
}
globalCounter() {
var self = this;
return self.childComponents(FoodCounterMixin)[0].counter() + self.childComponents(BeerCounterMixin)[0].counter();
}
}
MotherComponent.register('MotherComponent');