Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add binding mechanism #20

Closed
aaronj1335 opened this issue Jul 20, 2012 · 2 comments
Closed

add binding mechanism #20

aaronj1335 opened this issue Jul 20, 2012 · 2 comments

Comments

@aaronj1335
Copy link
Contributor

bind DOM elements to model fields

overview

the easiest way to explain is to start off with some examples

explicit binding

var $el = $('<span></span>'),
    binding = Binding({
        model: myModel,
        bindings: {

            // this is the model's field name, '.' is expanded to
            // nested model fields
            'myModelField.subField': {

                // any HTML snippet, either jQuery collection or
                // bare HTMLElement
                el: $el

            }
        }
    });

whenever myModel.myModelField.subField changes, the innerText of
$el will be updated with its new value. this is a one-way binding.

automatic binding to some fields in an HTML snippet

var binding = Binding({model: myModel, el: $someHtml});

where $someHtml refers to markup of this structure:

<div>
  <span data-bind=field1></span>
  <span data-bind=field2></span>
</div>

then whenever myModel.field1 and myModel.field2 change, the
innerText of their corresponding <span> elements will be updated.
this is also a one-way binding.

automatic binding to a widget instance

var myWidgetGroup = WidgetGroup($userForm),
    myUserModel = User.model.get(1),
    binding = Binding({model: myUserModel, widget: myWidgetGroup});

where $userForm refers to something like this:

 <form>
   <input type=email name=email placeholder=Email />
   <input type=password name=password placeholder=Password />
 </form>

in this case, since the <input> elements will be instances of
FormWidget, they will be bound to their corresponding
fields in myUserModel. these will be 2-way bindings.

further details for automatic binding

automatic binding algorithm works as follows:

  • take a DOM fragment (either bare HTMLElement instance, jQuery
    collection, or Widget instance),
  • check each element for data-bind attribute, if found, set up a
    one-way binding between the element and the field specified by the
    attribute
  • if no data-bind attr, check if the element corresponds to an
    instance of FormWidget, if so, set up a two-way binding between the
    widget and the model field corresponding to the widget's element's
    'name' attribute
@ghost ghost assigned aaronj1335 Aug 11, 2012
aaronj1335 added a commit that referenced this issue Aug 11, 2012
@aaronj1335
Copy link
Contributor Author

open questions:

  1. should we use the HTML attr data-binding or the shorter data-bind?

  2. there are (too) many different forms by which this could be instantiated:

    var binding1 = Binding(myModel, myWidget),
         binding2 = Binding(myModel, $someHtml),
         binding3 = Binding(myModel, instanceOfHTMLElement),
         binding4 = Binding(myModel, { /* bindings */ }),
         binding5 = Binding(myModel, myWidget, { /* more bindings */ });
    

    and that's not even taking into account the fact that we'll need to be able to specify options. i think a better approach may be to just instantiate it w/ one object:

    var binding = Binding({
        model: myModel,
        widget: myWidget,        // or 'el' in the case of $someHtml
        bindings: {
            /* optionally more bindings */
        }
        /* ... more options ... */
    });
    

aaronj1335 added a commit that referenced this issue Aug 11, 2012
implemented changes from #20 comment here:

    #20 (comment)
aaronj1335 added a commit to siq/bedrockjs that referenced this issue Aug 12, 2012
pertains to siq/gloss#20

i plan to replace both the siq/mesh Model and siq/gloss Widget `set`
functionality with this mixin.
aaronj1335 added a commit to siq/bedrockjs that referenced this issue Aug 12, 2012
aaronj1335 added a commit to siq/bedrockjs that referenced this issue Aug 14, 2012
aaronj1335 added a commit to siq/mesh that referenced this issue Aug 14, 2012
aaronj1335 added a commit to siq/mesh that referenced this issue Aug 14, 2012
aaronj1335 added a commit that referenced this issue Aug 14, 2012
what used to be Class.prop is now Class.nestedProp, and the Model class
from siq/mesh uses the Settable mixin.

pertains to #20
aaronj1335 added a commit that referenced this issue Aug 14, 2012
aaronj1335 added a commit that referenced this issue Aug 14, 2012
pertains to #20

i was making the assumption that all grids were backed by models, this
is not always the case... though maybe it should be...
aaronj1335 added a commit that referenced this issue Aug 14, 2012
aaronj1335 added a commit to siq/bedrockjs that referenced this issue Aug 15, 2012
aaronj1335 added a commit to siq/mesh that referenced this issue Aug 15, 2012
@aaronj1335
Copy link
Contributor Author

this has been implemented, so i'm going to close this issue.

there's still some work to be done before this is really useful though. we'd want to add some kind of mixin for convenience, which would allow us to do something like:

var MyBindableWidgetGroup = WidgetGroup.extend({
    // ...
}, {mixins: [Bindable]});

// and then the usage would be something like:

var someForm = MyBindableWidgetGroup($form, {model: someModel});

and then the big thing would be handling the results of a call to someModel.save() and someModel.refresh(). we would want the mixed-in widget to do stuff like disable inputs while saving and correctly display error responses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant