Blaze Components as "the new view layer"

Hi guys,

pre-print: I consider myself a javascript & meteor newbie and I am just working on my first big app.

I totally fell in love with Blaze Components (big thumbs up to @mitar) https://github.com/peerlibrary/meteor-blaze-components
and I am so confused by the whole React discussion. Hierby I vote for MDG keeping full Blaze-Support within core.

Why not simply have Blaze Components as the NEW Blaze?

Blaze was what originally draw me into Meteor and with the help of “Blaze Components” I am able to bring my app to the next level and keep it DRY.

I much prefer the syntax of Blaze Components and have NO intentions to switch to react as I don’t need react native support.

Is anyone else feeling like Blaze Components should be kept close to core?

I mean: this demo-code here shows all I need to structure my app really well into reusable components:

JS

// ===================
// COUNTER Super-Mixin
class CounterSuperComponent extends BlazeComponent {
  // COMMON template for Mixins
  template() { return 'CounterSuperComponentTemplate'; }

  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;
    log('click');

    self.counter(self.counter() + 1);
  }

  theGlobalCount() {
    var self = this;
    return self.parentComponent().globalCounter();
  }
}

// FOOD Counter
class FoodCounterComponent extends CounterSuperComponent {
  constructor() {
    super(
      {title: 'Food'}
    );
  }
}
FoodCounterComponent.register('FoodCounterComponent');

// BEER Counter
class BeerCounterComponent extends CounterSuperComponent {
  constructor() {
    super(
      {title: 'Beer'}
    );
  }
}
BeerCounterComponent.register('BeerCounterComponent');

// ===================
// MOTHER-Component
//  has access to to other components
//  to regulate interactive behaviour
class MotherComponent extends BlazeComponent {
  constructor() {
    super();
    log('constructor');
  }
  template() { return 'MotherComponentTemplate'; }

  globalCounter() {
    var self = this;

    var beerCount = self.childComponents(BeerCounterComponent)[0].counter();
    var foodCount = self.childComponents(FoodCounterComponent)[0].counter();
    return beerCount + foodCount;
  }
}
MotherComponent.register('MotherComponent');

HTML

<head>
  <title>blaze components</title>
</head>

<body>
  <p>Home</p>
  {{> MotherComponent}}
</body>

<template name="MotherComponentTemplate">
  <h1>MotherComponent</h1>
  <p>Global Counter: {{globalCounter}}</p>
  {{> FoodCounterComponent}}<!-- child components to MotherComponent -->
  {{> BeerCounterComponent}}
</template>

<template name="CounterSuperComponentTemplate">
  <h1>{{title}}-Counter</h1>
  <button>click me to count a {{title}}</button>
  <p>{{title}}-counts: {{counter}}</p>
  <p>GLOBAL-count (fromMotherComponent): {{theGlobalCount}}</p>
</template>
3 Likes

I’m glad you found the right tool for your job. :slight_smile: I on the other hand recently dropped Blaze Components in favour of new version of Manuel’s ViewModel package and saw a positive impact on the speed of development and I find my new code shorter, cleaner and more flexible.

So as much as I like Blaze Components a lot and had fun with it, I don’t share your feeling that it should get into core.

3 Likes

This has been discussed on a huge thread elsewhere on the forum, but the gist of it is: There are infinitely more people using React, building with React, developing learning resources in React, that MDG decided to tap into that vast network.

Can they make something like Vue/Blaze7 the default? Sure.
Does it make sense to make something like Vue/SpaghettiO89x the default? Not if they can spend that huge time elsewhere.

3 Likes

Alrighty - I guess you mean https://atmospherejs.com/manuel/viewmodel

Does viewmodel support Template inheritance like Blaze Component does?
How would you implement the above Food-Beer Counter in viewmodel? Can you give some quick sample code?

1 Like

@thebarty I’ll rewrite your example and paste it here today.

Well, I would vote for object composition instead of class inheritance.
Classes feels like good concept until u hit the wall.

And yes we are using class approach and blaze component.
But if I have some other choice more React way, but more object oriented + functional, I would prefer that one.

@brajt: Great stuff! I’m looking forward to your code. Maybe add some other gimmiks if you feel like showing off the advantages of viewmodel in comparision to BlazeComponents. :smiley:

@shock: Blaze Component’s Mixins kind of give you that, right? If not, can you give some “that would be perfect to have”-example code showing what you mean with “object composition”?

@thebarty @brajt

ViewModel has mixins and shared properties but that’s overkill for such a simple example:

<body>
<p>Home</p>
{{> MotherComponent}}
</body>

<template name="MotherComponent">
  <h1>MotherComponent</h1>
  <p>Global Counter: {{counter}}</p>
  {{> CounterComponent ref="foodCounter" title="Food" }}
  {{> CounterComponent ref="beerCounter" title="Beer"}}
</template>

<template name="CounterComponent">
  <h1>{{title}}-Counter</h1>
  <button {{b "click: increment"}}>click me to count a {{title}}</button>
  <p>{{title}}-counts: <span {{b "text: counter"}}></span></p>
  <p>GLOBAL-count (fromMotherComponent): <span {{b "text: parent.counter"}}></span></p>
</template>
Template.MotherComponent.viewmodel({
  counter: function() {
    if (!this.foodCounter) { // The children may not be available
      // this.children(); would have worked too but I prefer to be explicit.
      this.children().depend();
      return 0;
    }
    return this.foodCounter.counter() + this.beerCounter.counter();
  }
});

Template.CounterComponent.viewmodel({
  counter: 0,
  increment: function() {
    var count = this.counter();
    this.counter(count + 1);
  }
});
2 Likes

@manuel: Thanks for taking your time and demoing the app. :smile: