JohnLouderback / GDB

Generic Data Binder (GDB) for jQuery is a framework agnostic and extremely easy to use 2 way data binder. GDB binds views and models in realtime with live two-way binding and no hefty framework necessary.
http://gdb.thewebdev.guru/
Apache License 2.0
87 stars 11 forks source link

Problem with inserted HTML #14

Closed nevf closed 10 years ago

nevf commented 10 years ago

Hi John, I'm inserting some html into a page and then calling gdb with the model for the items I want to bind to in the inserted html. The same page has two other chunks of markup which gdb is bound to. When I type into an <input> in the inserted html the line:

eval("modelsToMonitor." + modelLocation + "=" + value);

raises an exception. When I look in the debugger the value of modelsToMonitor is not the correct model, it is instead the model for the first chunk of html gdb was called for on the page.

Looking at the code it appears that gdb only works with a single model, period as modelsToMonitor is set to the model for the most recent GDB call. Is that right?

I'm confused about the use of multiple gdb instances and whether this is even possible?

JohnLouderback commented 10 years ago

Sorry for the late reply. i just moved across the country for a new job and I need to use my phone for internet until I get service here.

To answer your question, there are two decent ways to accomplish what I think you're trying to do. If you'd like to create multiple instances of GDB, you can do so via var gdb2 = new GDB(model);. A more painless approach may be to have an object or array of models which is passed to a single instance of GDB. Whenever you need to add new model, you can simply push it to your original object or array of models.

nevf commented 10 years ago

@JohnLouderback I thought it odd that you hadn't replied, and that explains it. Best of luck with the new job.

I did try var gdb2 = new GDB(model); but that didn't work. gdb is in the global window namespace, even when using AMD.

I haven't made time yet to have a close look at the gdb code, however my thoughts are that modelsToMonitor should be an array that caches gdb models. The Object.observe code would look up this array to locate the appropriate model. My 2c.

JohnLouderback commented 10 years ago

Thanks for the well wishes! I'll look into GDB being in the global namespace. It should not be when using AMD. As for modelsToMonitor, it can be an array or object of models. I'm going to investigate this issue. If you're able to provide me with some example code, it may help expedite this process.

Thanks, -John

nevf commented 10 years ago

@JohnLouderback Hopefully this will show the issue.

<input type="text" data-bindto="login.name">

var model = { name: 'Neville' };
gdb( { login: model } };
<input type="text" data-bindto="page.title">

var page_model = { title: '' };
gdb( { page: page_model } );

GDB now only knows about the page model. So the following fails with an exception. model.name = 'John';

JohnLouderback commented 10 years ago

Hmm... Yes, there's definitely some strangeness going on with multiple instances here. If I may, and please correct me if this does not apply to your usage scenario, but why not do it this way?

<input type="text" data-bindto="login.name">
<input type="text" data-bindto="page.title">
var model = { name: 'Neville' };
var page_model = { title: '' };
var models={ login: model, page: page_model };
GDB( models );
nevf commented 10 years ago

Think along the lines of widgets, where each one is in a self contained module which only gets instantiated when used. And these widgets would use GDB. In other words I'm not creating a big monolithic single page app where a single GDB instance/call would suffice. Does that help.

JohnLouderback commented 10 years ago

Sorry for the misunderstanding. I see now. I'll work on figuring out where in lies the error. Since you're dynamically instantiating these widget, will you also need to destroy these instances? GDB does not currently have a method for uninitializing, but this could be added. Also, I've added a new feature to GDB for event binding, so stay tuned!

nevf commented 10 years ago

@JohnLouderback Yes I do think there should be destroy method.

JohnLouderback commented 10 years ago

I will upload a new version of GDB with a destroy method shortly. I have, however, found our culprit. The model is correct for each instance of GDB. The problem is that GDB is by default watching all elements in the body, regardless of which instance they belong to. The way to remedy this is to use the rootElementSelectorString option and set it to the root element for each widget respectively on each instance. An example value would be #widget1 like so:

<div id="widget1">
    <input type="text" data-bindto="login.name">
</div>
<div id="widget2">
    <input type="text" data-bindto="page.title">
</div>
var model = { name: 'Neville' };
var page_model = { title: '' };
var gdb1=new GDB({login: model},{rootElementSelectorString: '#widget1'});
var gdb2=new GDB({page: page_model},{rootElementSelectorString: '#widget2'});
JohnLouderback commented 10 years ago

Hi Neville, I've almost finished implementing the destroyInstance method, but the only issues I'm experiencing is "unobserving" the objects. Observation is done recursively in the object, and to "unoberve" an object you must also pass it the callback function which is being unobserved. The problem in my instance is that the callback functions are created dynamically and anonymously. It's getting late here, but I can't think of a way to remedy this problem just yet. I can certainly remedy the issue for the polyfill, but I'm afraid that by changing the polyfill I will break implementation with Object.observe native support in the future. Any thoughts?

JohnLouderback commented 10 years ago

So, just to keep you updated, I've fixed this problem. GDB now keeps an object whose property names are equal to the paths in the model to which the Object.observe callbacks belong, whose values are equal to the callback methods, so that the Object.observe callback handlers are no longer anonymous and can thus be "unobserved". All that's left to do before I upload this update is for me to update the documentation and add a couple of new examples. I'm very excited. The event binding feature and better handling of GDB instances is going to be very very cool.

JohnLouderback commented 10 years ago

http://gdb.thewebdev.guru/examples/?v1.1.3&page=multiple.html

nevf commented 10 years ago

Hi John, Just a quick thanks and heads up, all looks good.