bruth / synapse

Hooks to support data binding between virtually any object.
http://bruth.github.com/synapse/docs/
BSD 2-Clause "Simplified" License
150 stars 6 forks source link

Regarding binding registration and replacement #25

Closed erikschoel closed 12 years ago

erikschoel commented 12 years ago

Hi there,

I've been using Synapse more intensively and I think it's great.

One thing I have been struggling with: Would it be possible to keep a register of bindings with 4 properties:

  1. observer
  2. subject
  3. event
  4. id

with the latter being just any value usable from code, and then with the option "replace" added to the observe() and notify() options. With observe then the check is to see of the observer is already observing the events of type event with the same id, and then effectively replacing the subject. And the other way around for notify.

Or is this something I can better achieve otherwise?

Best regards,

Erik

bruth commented 12 years ago

Your sentences are somewhat fragmented, I am not entirely sure what you mean. Do you have an example or clarify your question?

erikschoel commented 12 years ago

Sorry, I'm Dutch :) let me try to improve:

example: $(field) = input field on screen model = backbone model wrapped in Synapse (is part of a collection)

/* A user click leads to --> loading a model from the collection --> rendering on the screen --> binding the fields to the model / /

model.observe(Synapse($(field), { event : 'change', observerInterface : 'handleFieldChange', id : 'field1' });

/* then a user click must lead to loading another model from the collection --> this will re-render --> so $(field) will change --> I want the model to observe the new field */

model.observe(Synapse($(field), { event : 'change', observerInterface : 'handleFieldChange', id : 'field1', replace : true });

/* Must: --> unbind the existing binding based on observer+event+id --> bind the new $(field) on the same id --> effectively replacing the binding */

I could of course try to fill the exact same fields on the screen instead of re-rendering, but I use $(field_container).empty() + mustache to re-render.

bruth commented 12 years ago

So it sounds more like you want to reuse an element in your view layer between multiple data sources (model instances in the collection in this case). There are a few methods for stopping or pausing observing/notifying listed here: http://bruth.github.com/synapse/docs/#object-api-channel-flow I don't see a real advantage to having another configuration option for this kind of behavior. One advantage of pausing notification/observing is if the element may be observing the original model again at some point.

bruth commented 12 years ago

Based on your description, this is the scenario I am assuming you have:

var model, button, input;

input = Synapse('input');
button = $('button');

button.on('click', function() {
    model = collection.create({...});
    input.stopObserving(); // or pause depending on the use case
    input.observe(model);
});

Or if the button toggles between objects in the collection:

var id;

button.on('click', function() {
    // get the `data-id` attribute on the button (maybe a button for each
    // model instance?)
    button.data('id');
    model = collection.get(id);
    input.stopObserving(); // or pause depending on the use case
    input.observe(model);
});
erikschoel commented 12 years ago

Thanks Bruth.. I've tried this and it works fine IF I use pauseObserving rather than stopObserving. In the latter example, when I use stopObserving then the input won't rebind to the model, that is, if the user clicks model 1, then model 2, and then back to model 1, in the last case then input won't rebind. If I use pause then it will, so that's fine.

Is this indeed the way you intended it to work?

bruth commented 12 years ago

If you use call pauseObserving, then of course you can use resumeObserving. If you use stopObserving, then calling resumeObserving will not work. It explicitly unbinds the underlying event handlers thus needs an explicit rebind via input.observe(model) in order to be setup again. If the later is not working (explicit observer after calling stopObserving) then that is a bug.