Model event firing after validate() completes.

Showing 1-23 of 23 messages
Model event firing after validate() completes. Kim Andersen 8/11/11 10:02 AM
Unless Im missing it somewhere it would be really nice to have an event fired after a model's validate() method completes.

Im aware that callers can pass an error callback in the options parameter on a model's set() method. However, Im looking for a handy way of letting the model itself know when a validate() is completed.

Below is what Im doing now at the end of my validate() method to get this behavior.
Note: I need to do it async so the validate() returns, otherwise attributes are not set.

validate: function()
{
    // Validate...

    window.setTimeout(this.validateComplete, 0);
}



Thanks
Kim

Re: [backbonejs] Model event firing after validate() completes. Andrew de Andrade 8/11/11 10:16 AM
just add a this.trigger('validate'); at the end of the validate() method.

> --
> The Unofficial Backbone.js Group
>

--
Q: Why is this email four sentences or less?
A: http://four.sentenc.es

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/11/11 10:42 AM
Hi there, thanks for replying.

Triggering an event at the end of the validate() method was my first try as well, but it doesn't work.
It seems the handler is triggered before the validate() method returns thus the attributes are not set, which is basically the problem.

Thats why Im doing the minimum timeout.


Kim
Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/11/11 10:44 AM
Sorry about being unclear about that.
I need the attributes set before the handler is called, which is why Im looking for an event that fires right after the model's validate() method completes.
Re: [backbonejs] Model event firing after validate() completes. Andrew de Andrade 8/11/11 10:50 AM
try adding a defer then, like so:

_.defer(_.bind(function(){
  this.trigger('validate');
}, this));

what do you mean by handler? do you have a commented gist with more details?

PS _.defer is a cleaner way of performing the minimum timeout of 0 so
that the stack can clear.

> --
> The Unofficial Backbone.js Group
>

--
Q: Why is this email four sentences or less?
A: http://four.sentenc.es

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/11/11 10:55 AM
By handler I mean my event handler, here "validateComplete":

_.defer(_.bind(function(){
  this.trigger('validateComplete');
}, this));


Anyway, basically same solution. I'll check out underscore's defer...
Sorry, no gist for this.
Re: [backbonejs] Model event firing after validate() completes. Andrew de Andrade 8/11/11 11:08 AM
cool deal. without viewing the source and seeing exactly what it is
you are trying to accomplish, it is difficult to think of any other
solutions.

If you are calling validate directly instead of indirectly via set(),
unset() or save(), you may be able to exploit the fact that
this.validate() returns true when successful.... i.e. if
(this.validate()) this.get('attribute');

> --
> The Unofficial Backbone.js Group
>

--
Q: Why is this email four sentences or less?
A: http://four.sentenc.es

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/11/11 11:31 AM
In my case its a view calling set() on a given model, so its a by-the-book scenario.

Although its basically doing the same thing I prefer underscore's defer() because its more readable.

Thanks ;-)
Re: [backbonejs] Model event firing after validate() completes. Andrew de Andrade 8/11/11 11:44 AM
if it's a textbook example, why do you need access to the attributes
immediately following the validate? are you updating the view? if so,
why don't you just watch the "change" event on the model that is
called after set/unset/save and is only called if validation succeeds?

> --
> The Unofficial Backbone.js Group
>

--
Q: Why is this email four sentences or less?
A: http://four.sentenc.es

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/11/11 1:20 PM
Maybe Im not doing it by the book.

It is a login form. Im using validate() to check username+password on keydown. The model triggers either "valid" or "invalid" which the view binds to and then enables/disables the login button accordingly.

How would you do that?




2011/8/11 Andrew de Andrade <and...@deandrade.com.br>

Re: [backbonejs] Model event firing after validate() completes. Derick Bailey 8/11/11 1:34 PM
I blogged about doing exactly that a while back. instead of using the validate() method (which is where i started, and ended up exactly where you are), i used the "change" event on the model, and bind to itself. then i do my validation in there.


i know it's skipping paste the built in validation method, but it was the best way to get the functionality i wanted.  hope that helps.

fwiw: i would love to see a "validated" event on models - one that fires after validation, telling us whether or not a model is valid.

  -derick-----------------------
END OF LINE

Derick Bailey
- @derickbailey
- http://derickbailey.lostechies.com
- http://derickbailey.tumblr.com

Muted Solutions, LLC
- @mutedsolutions
- http://mutedsolutions.com

Re: [backbonejs] Model event firing after validate() completes. Andrew de Andrade 8/11/11 1:37 PM
Instead of having the validate() method on the model trigger "valid"
or "invalid", have it return nothing (or false) if all is well. If
validation fails, have it return an error.

If you want it to do something on validation fail, set a failed
validation callback that disables the button. Reenable the button if
set() is called successfully (i.e. doesn't return false).

On Thu, Aug 11, 2011 at 1:20 PM, Kim Andersen <kimand...@gmail.com> wrote:

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/12/11 12:20 AM
Interesting we arrived at the same solution, Derick.

Andrew, I'll try your approach today which I think is probably the backbone way to go.
I'll let you know how it goes.


Kim

2011/8/11 Derick Bailey <derick...@gmail.com>

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/12/11 2:24 AM
Hi Andrew
I implemented your approach and find it much cleaner and MVC like. Plus I learned a bunch.

Thanks for your help.


Kim
Re: [backbonejs] Model event firing after validate() completes. Andrew de Andrade 8/12/11 8:05 AM
No prob!

Sent from my iPhone
--
The Unofficial Backbone.js Group
Re: [backbonejs] Model event firing after validate() completes. Derick Bailey 8/12/11 8:09 AM
Kim - can you share the end result? i'm really interested in seeing some actual code for this.

  -derick

--
The Unofficial Backbone.js Group



--
-----------------------
END OF LINE

Derick Bailey
- @derickbailey
- http://derickbailey.lostechies.com
- http://derickbailey.tumblr.com

Muted Solutions, LLC
- @mutedsolutions
- http://mutedsolutions.com

Re: [backbonejs] Model event firing after validate() completes. Derick Bailey 8/14/11 12:19 PM
If anyone is interested, I just updated my backbone.modelbinding plugin to support a scenario that would simplify this a little, using data-bind attributes. here's a blog post that discusses / demonstrates it: http://lostechies.com/derickbailey/2011/08/14/enabling-and-disabling-a-button-with-backbone-modelbinding/

  -derick
Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/15/11 12:25 AM
Hi Derick
Sure, I implemented it exactly like Andrew proposed.
Here is the pseudo-like code for a "forgot password" UI dialog that only holds one input field: "emailInput".
What makes this work is the fact that model attributes are only set if the model's validate() method succeeds = it does't return anything hence the documentation.

View
{
    this.model.bind("change:email", this.onEmailChange);
    this.model.set({email: $emailInput.val()}, this.onEmailValidationError);

    onEmailValidationError: function(){
        // Disable submit button.
    }

    onEmailChange: function(){
        // Enable submit button.
    }
}

Model
{
    validate: function(){
        // Validate email attribute and only return something if invalid, otherwise the email is set and the "change" event is triggered for you.
    }
}

Personally I find this approach very lean and readable, given you know a few facts about backbone.js itself.

Hope this helps.


Kim



2011/8/12 Derick Bailey <derick...@gmail.com>

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/15/11 12:38 AM
Derick, what does your plugin do?
Re: [backbonejs] Model event firing after validate() completes. Derick Bailey 8/15/11 6:05 AM
i like that - much better than the original way i solved this problem :)

  -derick
Re: [backbonejs] Model event firing after validate() completes. Derick Bailey 8/15/11 6:15 AM
my plugin (https://github.com/derickbailey/backbone.modelbinding) adds what i think is the only missing piece of backbone - convention based and declarative model binding. 

it allows you to remove a lot of the boilerplate and repetitious code that would normally be found in a backbone view. So, you can go from this:

SomeView = ... ({
  events: {
    "change #first_name": "firstNameChanged",
    "change #last_name": "lastNameChanged"
  },

  firstNameChanged: function(e){
    var value = $(e.currentTarget).val();
    this.model.set({first_name: value});
  },

  lastNameChanged: function(e){
    var value = $(e.currentTarget).val();
    this.model.set({last_name: value});
  },

  render: function(){
    // some rendering to populate `el` w/ contents
  }
});

to this:

SomeView = ...({
  render: function(){
    // some rendering to populate `el` w/ contents
    Backbone.ModelBinding.call(this);
  }
})

it uses conventions (that can be changed, fairly easily) to populate the model with the data from the form inputs.

it also allows you to use knockoutjs-like data-bind attributes on your view's html elements, to update your views with model changes instead of having to re-render the view every time a model changes. In the case of the example / blog post that i linked to below, i'm using the data-bind attribute to create the same button enabled / disabled functionality that we've been discussing on this thread. when you check or uncheck the box in that sample, the button will either enable or disable (depending on which of the two samples your looking at).

  -derick

On Mon, Aug 15, 2011 at 2:38 AM, Kim Andersen <kimand...@gmail.com> wrote:
Derick, what does your plugin do?

--
The Unofficial Backbone.js Group



--
-----------------------
END OF LINE

Derick Bailey
- @derickbailey
- http://derickbailey.lostechies.com
- http://derickbailey.tumblr.com

Muted Solutions, LLC
- @mutedsolutions
- http://mutedsolutions.com

Re: [backbonejs] Model event firing after validate() completes. Kim Andersen 8/15/11 6:31 AM
Interesting.
I used knockout a few months back and found most of it pretty useful, though still a bit rough maybe.

So far Im liking the renderering paradigm of backbone, especially when it comes to readability which I find vital on large dev teams.
In some ways the data-bind way of doing things are a bit too "under the hood"ish for me. Adding too many abstraction layers only adds to complexity for other developers maintaining your code. However, its a fine grained personal/team balance I guess.

Did you use knockout or your own plugin on any larger project, maybe with multiple javascript developers?



2011/8/15 Derick Bailey <derick...@gmail.com>

Re: [backbonejs] Model event firing after validate() completes. Derick Bailey 8/15/11 7:30 AM


On Mon, Aug 15, 2011 at 8:31 AM, Kim Andersen <kimand...@gmail.com> wrote:
Interesting.
I used knockout a few months back and found most of it pretty useful, though still a bit rough maybe.

yeah - i was initially impressed with KO as well. after watching several screen casts and reading through a handful of demos, though, i found it to be severely lacking in anything other than data binding. 
 

So far Im liking the renderering paradigm of backbone, especially when it comes to readability which I find vital on large dev teams.

+1

i love backbone's MV* structure, but still wanted to get some of the data binding advantages of KO. since the models are not compatible between the two, i wrote the plugin :)
 
In some ways the data-bind way of doing things are a bit too "under the hood"ish for me. Adding too many abstraction layers only adds to complexity for other developers maintaining your code. However, its a fine grained personal/team balance I guess.

i agree in general. when you get too many layers and abstractions, things get problematic and constrained by what the abstractions allow you to do.

but, backbone already does a lot of under-the-hood magic. the back-end servers also do that, whether your using rails, php, asp.net mvc, java, or any other back-end server. it's only a matter of training, like any other framework we already use, for a framework to be understood and readable by the team.
 

Did you use knockout or your own plugin on any larger project, maybe with multiple javascript developers?


i only have 1 coworker at this point (i'm an independent contractor/consultant/etc), and we use my plugin with backbone. it saves us a ton of time and code. 

  -derick
More topics »