-
a binding is just a link between a certain property on a model, and a piece of UI (FormWidget instance, <span> el, etc)
- it can be one-way (property change updates the UI) or two-way (change event from, say, and <input> el updates the model's property)
- the display value might actually be computed instead of displayed directly, the most common case of this would be showing a string value for some kind of token
-
it's convenient to group bindings, especially with forms, in which case a 'submit' event should call
.save()on the model -
in common cases all of the binding should happen automatically -- i'm thinking like a 'data-binding' attribute that we can add to the template. common cases include:
- a simple form (whatever 'simple' means…)
- a details pane, like the ones that are so ubiquitous in daft
-
we also want something really modular -- i think we've got a lot of the pieces already, but they need to be broken out, specifically:
- a
Widgetizerclass that just takes a dom fragment and reruns a bunch of instantiatedFormWidget's (basically breaking this into its own class) - a
BindingGroupclass that tracks the relationships between model properties and ui elements. this is a decent start. - an
ErrorPropagatorclass (preferably with a name that's not stupid) that understands how to take the exception thrown byModel#validate()and display the errors on the correctMessageListinstances. this is basicallyBoundWidgetGroup#processErrors(), but it should also handle strings a bit more intelligently
- a
-
ultimately we just want to instantiate one view (or maybe a mixin?), but i think it should combine these pieces to make everything work
-
aBindingGroupshould be able to handle more than one model (though there should be a main/default model so we don't need to type as much) -
we need to provide easy ways to extend the validation process. this should probably happen by inheriting from the model we want and overriding
.validate(). we also should consider async validations (like validating custom query expressions, which involves an ajax request) -- shouldModel#validate()always return a deferred??? something that's just resolved by default in the simple case? or maybe instead of throwing an error it should just always default to the deferred? (UPDATE: the answer is yes,.validate()always returns said deferred)
two more common cases that i don't believe we're handling right now:
when we call
.set(..., {validate: true}), no change events will be fired if the validation fails. this is essential so when the user inputs an invalid value, other model observers don't choke on the invalid value. the problem is that certain validations only happen server-side. so for example, if the server checks that each item has a unique name, then we could get in a situation where.set(..., {validate: true})succeeds, triggers a change event, and then.save()fails, but other observers of the model have updated themselves with the invalid value.it would be nice (necessary?) to be able to do something like
.set(..., {persist: true}), which wouldn't trigger a change event until the changes had been successfully.save()'ed (persist: truewould implyvalidate: true).we'll probably commonly run into situations where we want to add field-specific client-side validations. in the above scenario, you could imagine adding a validation that just makes sure a name is not currently in any of the models that the resource manager is aware of. the optimal api for this would look something like:
right now that'd be really difficult since we don't have good hooks into
validating single properties.
it seems more important to get the second one, since that will give us a good way of covering most of the situations that would optimally be handled by the first.