ViewModel 2 - A new level of simplicity

I agree with @deanius. This is great stuff, @manuel. I’ve overheard core devs speaking highly of your work :smile:

4 Likes

Manuel, at first glance I have to say I do like it. I’m gonna dive into it deeper, but real quick it’s all about the “2 way binding” thing right?

My conclusion with that is that it’s always been more glitz than actual punch. In reality, you don’t need the binding back. you don’t need your model populated on every keyup. You want to call one function at least to trigger saving its contents to mongo, right–so that one call can extract all the values from the form right then and save it. And of course you can optionally validate and perform various transforms from there. But the point is that in actuality there is very little difference between the model being bound on keyup and when you tell it so. It looks good in demos though! Am I wrong? What more abstractly/generally would you say are the biggest selling points to View Model?? Anything to help me wrap my head around it would be much appreciated.

1 Like

also what’s the input event?

'input #firstName': function(event, template) {
    template.state.set("firstName", $("#firstName").val());
  },

I feel like im having amnesia or something lol–there is no input event! …i assume its a shorthand for firing on all events–never heard of that, how long has that been in Blaze? Is that something somehow from jQuery too?

Great I am going to test if it will be compatible with our other Blaze packages. I am looking for an Angular replacement with data binding. Angular in Meteor is not compatible with other packages. Keep good working.

@deanius @rdickert @satya

Thank you for the kind words. I really appreciate it.

@satya

I added a what’s new section to the documentation.

is this backwards compatible because I see you simplified the syntax?

It is not backwards compatible. The library would have ended up a monster had I included the new features and still be backwards compatible. Another reason is that v1 required a monkey patch for Meteor. I got chills every time there was a new Meteor release. That’s gone now.

did only the that syntax change, or did you add features?

It has a bunch of new little things here and there which makes a much nicer experience for the developer. An example is much better errors. You now get something like:

The view model for template ‘person’ doesn’t have a ‘names’ property. See https://viewmodel.meteor.com/docs/viewmodels#defining for more information.

Another is how you don’t have to name your view models for them to persist across hot code pushes and save the state on the url.

did you make any other improvements?

It is much faster in terms of binding the elements and updating the view models. That’s because I did away with a ton of legacy stuff which nobody used (like being able to bind a view model to any element, not just a template).

@faceyspacey

input is a standard event: https://developer.mozilla.org/en-US/docs/Web/Events/input

Regarding 2 way binding. If you look at any React example which has input elements, you will find that they’re doing 2 way binding manually (since React doesn’t provide it). They listen for changes, manually update the state of the component, and do the 1-way bind on the template. Angular 2 got “rid” of two-way binding but ended up providing developers with a shortcut to do just that. The reason is simple, it is a common pattern to simplify the way you deal with element values.

I was going to define view models, how they work, why they make life so much easier, etc. but I think it’s better if you experience it yourself. Take a relatively small part of one of your websites (a template with blaze, template/controller with Angular, or component with React) and re-write it using ViewModel. Don’t pick something so small that there’s no code to back the view, and don’t pick something so big that it feels daunting. The ViewModel version will have less code and it will be simpler to read, write and reason about.

@charliecl

I haven’t tested v2 with other packages yet but it should work just fine with pretty much everything else (autoforms, easysearch, etc.) It makes life easier for javascript controls too. You can reference the html elements as part of the view models. For example:

<template name="example">
  <input type="text" {{b "ref: nameInput"}}>
</template>
Template.example.viewmodel({
  onRendered: function() {
    this.nameInput.makeFancy();
  }
})

Look Ma! No id on the html element or html references in my code!

4 Likes

Hi @manuel,

I really like your VM. But how do you write the new binding syntax in Jade?

I just tried guessing your example in the doc like:

  button('{{b "enable: canGreet, click: greet"}}') Greet

But it’s illegal .jade

Not to mention more quote pairs like:

  <label {{b "text: 'My name is: ' + fullName"}}></label>

Don’t want to lose the simplicity of Jade. Thanks. :smile:

2 Likes

After a bit of research, there’s actually a solution to replace the most used jade compiler: https://github.com/dalgard/meteor-jade

such that I could write the following .jade to reproduce the example in doc:

template(name="greeting")
  label First Name
  input(type="text" $b="value: firstName")

  label Last Name
  input(type="text" $b="value: lastName")

  input(type="checkbox" $b="check: agree")
  label($b="text: 'My name is: ' + fullName")

  button($b="enable: canGreet, click: greet") Greet
  button($b="click: clear") Clear

Perfect! :sunny:

3 Likes

To avoid conflict string to tag, I usually used single quote. Can I apply single quote in ref below?

<template name='example'>
  <input type='text' {{b 'ref: nameInput'}}>
</template>

Sure, its just javascript =)

Hello, Manuel, thank you for all the hard work!
So does v2 work with jade?

Sure, look at daveeel’s post up there

@avalanche1 I use it both with Jade and CoffeeScript and it works perfect.

2 Likes

Hmmm, and will it be compatible with ‘Blaze2’?

Looks interesting, but I don’t want to stick with any package which will be deprecated in future because it’s depends on Blaze1.

Unfortunately MDG has created this situation where no one knows what’s going to happen and everyone is looking for a life raft (as deanius said). Even worse is that there is no time frame for any of this. The transition to React could happen in a month or two or maybe a year from now. No one knows.

But since when did the lack of facts and figures stopped us from speculating? So let’s do just that!

Based on a complete lack of information I hereby predict that MDG will provide a way to transpile templates (and the code behind) into React components. This project will work beautifully at the beginning. The project will decline as Meteor continues to push React as the canonical way of working with Meteor. Within a year it will be clear that the project isn’t receiving any love because it’s just there for legacy purposes. Then while you could technically write your views with templates, it would be clear that React is the new Meteor way of doing things.

Getting more serious…

Where does that leave ViewModel?

ViewModel will continue working as long as there’s a way to transpile templates into React components. So ViewModel will continue working as long as MDG maintains Blaze 2 (or whatever the transpiler is called).

8 Likes

What I read is that ViewModel pre-defined many events for form processing. So what about new events such as touch screen or remote controller? An example is swipe event in gesture recognizer.

Do you have a simple echo input example like the one in Angular? That is input text in a text box and instant displayed as you input under the box. That is a typical hello example of Angular.

@charliecl

You can put any event inside {{b "someEvent: someMethod"}}. In fact, there is no click bind. When you do {{b "click: sayHello"}} the click is assumed to be the event (because there isn’t a click bind) and is attached to the element with sayHello as callback.

I think this is what you mean by an echo example:

<body>
  <input type="text" {{b "value: message" }}>
  <p {{b "text: message" }}></p>
</body> 
Template.body.viewmodel({
  message: ''
});

If there is one idea that drives the design of ViewModel, it is this:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.

-Antoine de Saint-Exupery

1 Like

In fact, there is no click bind. When you do {{b “click: sayHello”}} the click is assumed to be the event (because there isn’t a click bind) and is attached to the element with sayHello as callback.

In fact this had me going blindly through the documentation in order to find a chapter about events. Ultimately I found the explanation, but It would be nice to define it as a separate chapter of Bindings for new users, even if it’s just 2-3 lines of “don’t worry, all events are there by default”.

1 Like

Hm, ok, maybe I am naive but I always gravitated to the solution where I could get from A to B with writing as little code as possible. I think current blaze with ViewModel is a rather smart and elegant way and doable for people who don’t have that much time to sink into a computer because you’ve got a job, a kid, etc.

I was doing Django for a few years before Meteor and left because it got to fat and complex to work with - also the entire community got hang up discussing tiny things for ages, progress wasn’t possible anymore.

I kind of feel the same when I read this, initially Meteor seemed to be something tiny but smart and agile. This idea with react is probably a good one (not enough of an expert to tell) but from a weekend programmer point of view it seems I’ll end up with yet another hippo really soon now and thus have to look out again for something less complex…

Of course, if you have 20+ hours a week to spend then Meteor is probably going to be the go to thingy for you, even more so after that react plan springs into existence. For people like myself with a day job and kids, blaze and ViewModel is something that attracts me because it’s within my time frame I can invest. I look at the react site, the code examples, scroll down… pause a little and leave, never come back. To much, to complex.

3 Likes

@manuel By the way: Will there be a larger documentation for ViewModel 2? I’m just wondering, because the doc of ViewModel 1 was more extended.

//E: Ah I see, there is now an older link to the V1 doc :slight_smile: