Great examples! Thanks. I will use viewmodel 2 in my current project.
I really like what I’m seeing with ViewModel2, but I just can’t bring myself to take on something with a dependency on Blaze due to the new direction Meteor is being taken in.
It will be harder for any project like this, the ones that live outside of the Meteor recommendation. Right now, the mindshare is going to swing to React, and along with it the tools, the packages, the help etc.
I didn’t read that in the latest statement of MDG’s CEO. Blaze will be still the Meteor recommended way, but this can change in the future. At the moment, there are cases where you are faster with Blaze/ViewModel and some where React may be the better choice. Learning both shouldn’t be a problem for a developer - and if Blaze will be deprecated in 2 or 3 years, that shouldn’t be a problem. Look at the Angular guys who have to deal with breaking changes in Angular 2.
I wish you were right, but I don’t think you are. Here’s a link to the thread where I give my take on this.
I have tons on Blaze code in production, and would love to use something like ViewModel, I just can’t after the recent MDG announcements. I guess if I get the bandwidth I’ll slowly start migrating to React sometime after 1.3 drops.
And it’s not just React, but the entire Meteor stack will morph into a stack that compliments React – basically a modified Facebook stack of sorts.
As a small startup, with a relatively large application (well over 100 Blaze screens and counting), I have to ask myself, does it make sense to invest more in Blaze and take on something like ViewModel or should I invest that time (money) into the migration to React?
Hopefully packages like ViewModel will come along that will make React easier like they have with Blaze.
I hear you.
TLDR: I’ll continue to work with Blaze/ViewModel for all applications that aren’t big enough to warrant hacking my way to get code splitting and SSR. Quite a lot of projects fall under this category (YAGNI applies here).
I usually create web apps, not websites, so the only thing I would love for MDG to come out and say is that Blaze will get lazy loading so it can be used on really big projects. Meteor has too many clients on Blaze so they’re not dropping Blaze (as in break it) any time soon.
Consider the following:
-
There isn’t anything out there that takes care of so many problems for me than Meteor (moving data between client and server, database reactivity, authentication, authorization, configuration, etc.)
-
There isn’t anything out there that allows me to write cleaner and simpler code than ViewModel (the whole component communication and state problems just disappear).
So if a Meteor/Blaze/ViewModel solution works beautifully today, why would I make my life harder just to get to the same point tomorrow? Why would I rewrite an app that, if left alone, will continue working tomorrow as well as it does today?
That said, if MDG ever comes out with a solution for React that doesn’t require hacks to get SSR, lazy loading, hot reload, etc. (afaik, the current react
package doesn’t offer any of that) I will make a ViewModel that sits on top of it (the same way it now sits on top of Blaze). Here’s an example of what it could look like:
pacman.vmc
<PacMan>
<div>
<svg b="attr: { width: width, height: height }" style="border: 1px solid black;">
<path b="attr: { d: path }" fill="yellow" stroke="black" stroke-width="2" />
</svg>
<PacManOption ref="largeArc" title="Large Arc?" name="largeArc" value="0" />
<PacManOption ref="closePath" title="Close Path?" name="closePath" value="0" />
<PacManOption ref="sweep" title="Sweep?" name="sweep" value="0" />
<input type="range" b="value: radius" />
</div>
</PacMan>
<script>
PacMan = {
radius: 0,
path: function() {
return "M 100,100 L220,60 A "
+ this.radius() + "," + this.radius()
+ " 1 " + this.largeArc.value() + "," + this.sweep.value()
+ " 220,140" + (this.closePath.value() ? "Z" : "");
}
}
</script>
pacmanOption.vmc
<PacManOption>
<div>
<span b="text: title" />
<input type="radio" value="1" b="name: name, group: value" /> 1
<input type="radio" value="0" b="name: name, group: value" /> 0
</div>
</PacManOption>
I don’t think MDG will do anything of the sort. This is post summarizes how I think it’s going to go down with Blaze.
Right, again, it will just sit as is, as it has for a while now, until React comes up to parity both in integration and package coverage.
This will also be true once the transition of Meteor to the Facebook stack has taken place. I’m sure there will be custom solutions to make the Facebook stack easier than it is without Meteor.
I’m sure this is true to some degree (I can’t speak to it because of course I haven’t actually used it), but this is beside the point. Again, I would love to use ViewModel (it looks wonderful), and am not looking forward to using React – but if I want to say current with Meteor and the way the ecosystem is going, I need to start making the switch at some point after 1.3. I think ViewModel over React would take off.
Simply, because the community support, the examples, the documentation, the packages, the mindshare of Meteor is going the way of React and the complimentary tech around the Facebook stack. If you want to live in this world you must stay current.
The way I see it, you must choose to:
-
say current and in my case migrate to React and Redux (or whatever data transmission layer is going to prevail),
-
stay where you’re at and take on package management and all this entails as they stagnate – for example bug fixes, if you want features you’ll need to do this yourself or find like minded side communities, help will subside as mindshare moves on, etc. There’s too many risks for a small startup like mine to fall too far behind the front.
-
switch to alternative frameworks, of which there are relatively few. In my case, I’ve invested too much in Meteor as I have a large production application.
This would be excellent, I can only hope.
I agree with your sentiment but I disagree with your conclusions =)
I just don’t see the value in chasing the latest trends (making my life harder in the process, working with something I don’t like) when the worst that can happen is for my apps to work tomorrow the same way they do today. I am perfectly comfortable with that.
+1 insightful
This has been my biggest reluctance of investigating ViewModel further: both ‘View’ and ‘Model’ are overloaded terms, with many different interpretations. It’s just too easy to confuse it with MVC terminology. The technology looks perfectly fine; but the API adds confusion.
The value for me at least is getting code splitting (right now my client even the templates they don’t always use), UI/Server performance enhancements, SSR, tentatively more package coverage, and on and on.
I wouldn’t call waiting several releases chasing as you say, and I when I do start the React upgrade it will go slowly. I’ll wait for at least 1.3, maybe even sometime after that – I want things to settle down more before I start to migrate.
The worse for me looking out on the horizon is broken/abandoned packages, waning community help/support, and unaddressed bugs.
I love working with Blaze, but its future is uncertain and I would hesitate advising others to invest in it unless/until MDG turns it into true community driven OSS.
Please, not another blaze v react discussion…
Let’s keep this topic a Viewmodel Q&A. I like it much better that way.
Q re ‘change’ binding:
docs say ‘The change binding executes a function when the value of the bound property changes.’ This means I have to explicitly add a ‘value’ binding - otherwise change event fires only on blur.
In my case I don’t need to bind that particular input field. I only need to catch the change event. In that case I use standard input
event.
So what’s the reasoning behind having this ‘change’ binding?
You’re right that if you don’t need the value of the input (just need to know when it changes) then you’re better off using the element’s events. In the case of an input box you probably want to do:
<input type="text" {{b "input: doSomething"}}>
That said, I’ve never had an input box on a page which I didn’t use the value.
The change
binding exists because you don’t always have an element’s event. It functions kinda like an autorun for a single value associated with an element. For example if you wanted something to happen when the visibility of an element changes you could use an autorun, or you could just use the change binding:
<template name="example">
<div {{b "if: displayContent, change: do_Something_When_displayContent_Changes"}}>
content
</div>
</template>
Children demo references parent.remove(_id)
to access parent’s properties from mark-up. But doesn’t mention the same functionality for children.
Is there a way I could access a specific child’s property from mark-up?
Like div($b= "text: children('childVM').someProperty()")
?
Currently I’m forced to create a special property on the parent which reads someProperty
of childVM
.
I added .child
in v3.1.0 (I also updated the documentation)
The reasoning is that if it makes sense for ViewModel.find
to have the .findOne
counterpart, then it makes sense for .children
to have a .child
too.
So you’re now able to use div($b= "text: child('childVM').someProperty")
, but I have a feeling you can probably do it with a reference to the child too.
@manuel,
Can I use ref-binded property in VM.share
?
This doesn’t work:
<template name="binding">
<input {{b "ref: color"}} >
</template>
ViewModel.share({
car: {
color: ''
}
});
Template.binding2.viewmodel({
share: 'car'
});
Ref is for subtemplates, not for html elements. This way, ref doesn’t keep value, but a reference to subtemplate object.
Use viewmodel bindings instead.
I think you meant to use <input {{b "value: color"}} >
(not ref)
You can get a hold of elements with ref
as well. An example is when you want to apply a JS function to an element:
<template name="example">
<select {{b "ref: countriesElement, options: countries"}} ></select>
</template>
Template.example.viewmodel({
countries: ["Afghanistan", "Bahrain"],
onRendered: function() {
this.countriesElement.dropdown();
}
});
btw, I just added a new binding, refGroup, which allows you to manipulate multiple elements at a time.
<template name="example">
<select {{b "refGroup: dropdowns, options: countries"}} ></select>
<select {{b "refGroup: dropdowns, options: people"}} ></select>
</template>
Template.example.viewmodel({
countries: ["Afghanistan", "Bahrain"],
people: ["Alan", "Brito"],
onRendered: function() {
this.dropdowns.dropdown();
}
});
@manuel I saw a version bump and a video explaining some of the changes, but unfortunately it’s unavailable to me (?).
Perhaps it good to write a little about it here too?
For the video see https://viewmodel.meteor.com/about
For the changes see https://github.com/ManuelDeLeon/viewmodel/blob/master/HISTORY.md