ViewModel 2 - A new level of simplicity

Hey @manuel,
I’ve just remebered that you were working on a ViewModel for React :smile: - are there any updates on this? I’m now on my first React project and missing the good old ViewModel way. If there will be a ViewModel for React, will it have the same functionality like the one for Blaze or are the (structure) differences between Blaze and React too big for that?

It’s coming along just fine but I took a break to introduce validations. Soon you’ll be able to do something like:

Template.example.viewmodel({
  firstName: ViewModel.property.string.notBlank
    .validMessage('First name looks good')
    .invalidMessage("First message can't be blank or end with an X")
    .checkAsync((value, done) => {
      // Simulate an async call to the server
      Meteor.setTimeout(() => (value.endsWith("X") ? done(false) : done(true)), 1000)
    }),

  lastName: '', // It's a string so it defaults to ViewModel.property.string

  age: ViewModel.property.integer.min(18)
    .invalidMessage("Must be at least 18 years old")
    .validMessage("Is an adult (at least legally)")
})

As for React, it’s just an implementation detail. You’ll be able to work with it exactly like you did before (they aren’t that different at a fundamental level). For example instead of writing:

<template name="Example">
  <div>
    <input {{b "value: message"}} type="text">
    <label {{b "text: message"}} ></label>
  </div>
</template>
Template.Example.viewmodel({
  message: ''
});

You’d write:

Example({
  message: '',
  render() {
    <div>
      <input b="value: message" type="text" />
      <label b="text: message" />
    </div>
  }
})

I think we can agree it’s a cleaner implementation of the same concept.

5 Likes

I think it’s safe to assume that we’ll see a whole brand framework by Manuel one day :grin:

So, as now x.meteor.com apps are gone, where are all the docs and models of ViewModel?

http://viewmodel.org

1 Like

Manuel, could you add to viewmodel properties the name of template to which it is attached. For now it’s very hard to understand when debugging what exact viewmodel I am looking at when I have an array of viewmodels.

@Volodymyr

Sorry about that, the forum doesn’t let me update the links in the original post =/

@avalanche1

I added the property but it won’t be available until the next release. As for a framework, don’t bet on it. I’m not as interested in reinventing the wheel as I am in making aerodynamic.

Manuel, you should mention Meteor.isDev on viewmodel.org. :point_up:

Is there a way to make a global helper, available to all viewmodels, without explicitly declaring viewmodel.share in each viewmodel? Similar to Template.registerHelper

Thank you @manuel, these new features will make ViewModel even more unbeatable.

While the documentation on https://viewmodel.org/ is great as a reference, I hope that one day more writers will take the time to create some articles about the actual use of ViewModel. Still learning the ins and outs in a small side project, and at times it would be great to see how others are using it.

Although I still don’t quite understand why ViewModel is not getting more love, especially from ppl who like to stay on Blaze, perhaps your ReactVM implementation will get the attention it deserves!

Of all the features that fall in the category of “devs can shoot themselves in the foot if they use it poorly”, this is the only one that gives me pause. The gains are so little and the potential messes are so huge that I really don’t want to implement it. I may change my mind in the future but for now I think it’s a bad idea.

Manuel, I wonder if you know: does having many (like a 100) hidden elements (if property = false) sitting in dom with display:none impacts browser performance? Wouldnt it be better to just not render them into dom similar to Spacebars #if?

Performance wise display:none should be faster because it doesn’t have to insert or remove the element from the dom, just recalculate the layout.

I’m pretty sure it falls under the category of “the difference just doesn’t matter”.

1 Like

Manuel, can we add isRendered property (and isCreated) to VM which is automagically set to true when template has rendered?

.templateInstance has those properties.

Cant find it…

On the view
(needchars)

Ok, found it! But are they reactive sources? The whole point of initial suggestion was to be able to use them in an autorun.

There’s no point in using autorun for that. Use onCreated and onRendered.

Scenario: I have a list of post previews with post summary. Each has open and edit buttons.
When I click ‘openPost’ button I want a modal to open which contains detailed post information.
When I click ‘editPost’ button I want the same modal but in ‘edit mode’ where I can edit my post.
This is the pseudo-code:

view:
template 'postList'
  each post
    post summary here
    openPostButton($b click: openPost)
    editPostButton($b click: editPost)
template 'post'
   detailed post data here
   editPostForm($b if: editMode)
controller:
postList.viewmodel
  openPost: -> open_post_in_a_modal
  editPost: ->
    this.openPost()
    setInterval( if viewmodel.findOne( 'post') then viewmodel.findOne( 'post').editMode(true))

As you can see, I wait for ‘post’ viewmodel to be present and then turn on ‘edit mode’. I could use a session, which will be set to true in post tmpl onrendered callback, but then I’d have to maintain that session (delete and re-create…) - these are all suboptimal solutions.

That’s why I was asking for vm-inherent property in the first place.