I have been seeing the term "binding" and "live-binding" more and more recently, especially in JavaScript frameworks like Ember.js, Can.js, Knockout.js, and Backbone.js, and more traditionally, in Cocoa and Objective-C, and wonder what exactly a binding is? (and what exactly is a "live-binding"?).
It seems that from a loose sense, we can "bind A to B", and then we can say, "A is bound to B", and that means changes in B will be reflected in A -- automatically, without the user worrying having to set up an observer but the observer is set up earlier automatically and notified automatically when B changes.
And when we do that, we are creating a "binding".
And from a stricter sense, it seems the Cocoa and Objective-C defines it like this: a binding is a property foo of Object A, and this property observes and get changed to the value of property bar of object B. How it happens, we don't care and it is supposed to be hidden (like a black box), and usually it is implemented by the Observer Pattern. So the word "binding" actually means a "property", not an action -- and this property observes and get changed to the same value as the other property has.
And this binding is not limited to UI elements being bound to data. It can be an outer, larger UI element that contains a smaller piece of UI element, and the outer UI element has a property that is bound to the inner UI element property. Or it can be one non-UI data property bound to another non-UI data property.
Is this what a binding is exactly? And what about a live-binding?
I'm not sure of the history, but my guess would be that the term "binding" in this sense sprang from the term "data-binding." "data-binding" is indeed an action: it's populating UI controls with values from the actual data, AKA model, for example when fields in a form get filled with data from a database and get automatically updated, using the Observer pattern as you mentioned. I think the main distinction with binding is one-way versus two-way: in two-way data-binding, user input also gets synchronized back to the model, rather than data only syncing from the model to the view.
"bind" is a verb, and the verb form of "data-binding" would be "bind data" or "perform data-binding." The second example demonstrates that "data-binding" is also a noun, which could be defined as "the act of binding data/model properties to UI/view properties". With respect to the noun version of "binding" by itself, I think you're correct that it usually refers to an individual binding between two properties. To demonstrate this visually, suppose that the dots represent two properties that are bound to each other:
• ----- •
The "binding" here is the line between them.
To get more specific, a one-way binding could be represented with a single arrow:
• ----> •
And a two-way binding with two arrows:
• <---> •
"live binding" is a term that's just used to indicate that the Observer pattern is being used. My guess would be that the desire to distinguish a "live binding" probably came from web developers who had previously worked with frameworks where data-binding happened only once per HTTP request, when the page was first being loaded. Now that Javascript-heavy web apps are becoming the norm (partially thanks to ajax), there's no reason not to use the Observer pattern as suggested by the original definition of MVC, so "live binding" is probably an unnecessary term with regard to RIAs or native desktop or mobile apps.
As an aside, Trygve Reenskaug's original vision of MVC (he invented it) is fundamentally about reflecting the end user's mental model in the system so that the "Model" is something that the user is almost manipulating directly (or at least feels that way to the user). So the Observer pattern (or at least some mechanism to keep Model and View in sync without reloading the page) is essential to it and web development frameworks that have most of the code on the server-side aren't really MVC as originally conceived but rather a variant that follows the same general idea in terms of code organization. Modern Javascript frameworks for primarily client-side apps make real MVC possible for web development.
Back to a point you made in your question, I think you're also correct when you say that a binding isn't necessarily just between a model property and a view property; it could be between two model properties (usually on different models), or between two view properties. But I would disagree with your assertion that "binding" is only a noun with respect to programming - obviously in English it's the noun form of the verb "bind," in other words "the act of binding," and I think that's a valid usage in programming as well. So essentially what I'm saying is that it has a double meaning, but I think the definition you proposed is the most common. Here's my attempt at a formal definition:
Binding.
A connection between two properties (usually in two different objects) which keeps the properties in sync with each other, i.e. having the same value. The synchronization can be either unidirectional or bidirectional.
The act of initiating such a connection.
Binding in a very simple sense means to link, suppose you have a progress bar and a variable X, each time you tap a button the value of X increments. using Binding you can take the value of X(each time it increments) and show it on the progress bar. In the following line of code in C# "pb" is the progressbar and TapCount is the variable where total taps are being saved. It shows the value of "pb" has been bound to the variable TapCount
public void tapping
{
pb.Value = TapCount;
}
It's not dissimilar from the original use of the .bind method in vanilla javascript: you bind the scope of an object to a method.
Consider this.iterable.map( this.flush ) and this.iterable.map( this.flush.bind(this)). In the first, we're simple running a method on each interation of the iterable property on this - but in order for the this.flush method to access the this property, you must bind it to this.
In the same way, in frameworks like Ember, the model is a declaration. In order to populate that model from a remote source, you need an instance. In order to modify the model from handlebars, you need an instance. If your UI changes immediately effect the model instance - they're bound.
Pseudo-coded:
UI.view.bind(modelInstance)
RemoteSource.bind(modelInstance)
"Live-Binding", in my experience, is the binding of the data to the remote source immediately on change in the UI.
Pseudo-coded:
UI.view.bind(modelInstance)
RemoteSource.bind(modelInstance)
modelInstance.onChange(RemoteSource.update.bind(modelInstance))
The term 'binding' mostly used in client side development. Take for example you create a html webpage that show the temperature.
<div id="temp_value"> 77 °F </div>
Now you want to update this value as the temperature changes while you continuously make an AJAX request to the temperature provider API. In that response you receive a temperature value which should update your UI accordingly.
This need to update the HTML with the Javascript variable or similar gave rise to the concept of binding.
When you create something that keep your DOM in Sync with the change in any JS variable that can be DOM - Variable pair can be said as bind to each other.
There is also a term called two-way binding where any change in DOM updates the binded JS variable and vice-versa.
Related
So I have this Qt application with a QTreeView with a custom model (derived from QAbstractItemModel) and a custom model proxy for filtering (derived from QSortFilterProxyModel). More or less straightforward (somewhat similar to the and works fine) and works fine in terms of functionality.
The view shows a two-column tree with key-value pairs. The keys are updated very rarely but the values are updated frequently (a lot of entries with several updates every second each). In the proxy model I overload filterAcceptsRow to define visibility based on the key column. But every value change emits a dataChanged signal causing the view to call the proxy (filterAcceptsRow) again and that call is somewhat expensive (evaluate a regex on the element and its children). There is some room for optimization in filterAcceptsRow by caching all the calculations but it would be preferred to limit the calls to that function. Can it somehow be limited what columns trigger the calls to the proxy?
You have any advise for me?
Edit: Thanks for your input. I wasn't aware of dynamicSortFilter. I disabled dynamic sorting and also I connected the dataChanged-signal from the model to see if the key-column was changed and called invalidate in that case. That solved it.
If you look at the code for QSortFilterProxyModel you'll see that most of the work is only done when dynamicSortFilter is enabled. I guess that is the case for your code.
Can you live without it? Maybe call invalidate() once every 100 updates or second, depending on which happens first.
I had the same problem, solved it by emitting dataChanged signal from the proxy model itself, not from the main model. Alternatively, you can disable dynamic sort/filtering (dynamicSortFilter property) and call it manually when you want to filter or sort.
Also, I'm not sure, but maybe simply specifying the column in dataChanged signal will do it for you.
I have a custom UITableViewCell, and when the user clicks a button i make a request to a server and update the cell. I do this with a NSUrlConnection and it all works fine (this is all done inside the cell class) and once it returns it fires a delegate method and the tableivew controller handles this. However when i create the cell in the tableview, i use the dequeue method and reuse my cells. So if a cell has fired a asynchronous nsurlconnection, and the cell gets reused whilst this is still going on, will this in turn erase the current connection? I just want to make sure that if the cell is reused, the actual memory that was assigned to the cell is still there so the connection can fulfil its duty??
You can customize the behavior of a UITableViewCell by subclassing it and overriding the -perpareForReuse method. In this case, I would recommend destroying the connection when the cell is dequeued. If the connection should still keep going, you’ll need to remove the reference to it (set it to nil) and handle its delegate methods elsewhere.
It's never a good idea to keep a reference of a connection or any data that you want to display in a cell, no matter how much of effort you put into it afterward to work around to arising problems. Your approach will never work reliable.
In your case, if the user quickly scrolls the table view up and down, your app will start and possibly cancel dozens of connections and yet never finishes to load something. That will be an awful user experience, and may crash the app.
Better you design your app with MVC in mind: the cell is just a means to display your model data, nothing else. It's the View in this architectural design.
For that purpose the Table View Delegate needs to retrieve the Model's properties which shall to be displayed for a certain row and setup the cell. The model encapsulates the network connection. The Controller will take the role to manage and update change notification and process user inputs.
A couple of Apple samples provide much more details about this topic, and there is a nice introduction about MVC, please go figure! ;)
http://developer.apple.com/library/ios/#documentation/general/conceptual/devpedia-cocoacore/MVC.html
The "Your Second iOS App: Storyboards" also has a step by step explanation to create "Data Controller Classes". Quite useful!
Now, when using NSURLConnection which updates your model, it might become a bit more complex. You are dealing with "lazy initializing models". That is, they may provide some "placeholder" data when the controller accesses the property instead of the "real" data when is not yet available. The model however, starts a network request to load it. When it is eventually loaded, the model must somehow notify the Table View Controller. The tricky part here is to not mess with synchronization issues between model and table view. The model's properties must be updated on the main thread, and while this happens, it must be guaranteed that the table view will not access the model's properties. There are a few samples which demonstrate a few techniques to accomplish this.
I have several graphs. The breadth and depth of each graph can vary and will undergo changes and alterations during runtime. See example graph.
There is a root node to get a hold on the whole graph (i.e. tree). A node can have several children and each child serves a special purpose. Furthermore a node can access all its direct children in order to retrieve certain informations. On the other hand a child node may not be aware of its own parent node, nor other siblings. Nothing spectacular so far.
Storing each graph and updating it with an object database (in this case DB4O) looks pretty straightforward. I could have used a relational database to accomplish data persistence (including database triggers, etc.) but I wanted to realize it with an object database instead.
There is one peculiar thing with my graphs. See another example graph.
To properly perform calculations some nodes require informations from other nodes. These other nodes may be siblings, children/grandchildren or related in some other kind. In this case a specific node knows the other relevant nodes as well (and thus can get the required informations directly from them). For the sake of simplicity the first image didn't show all potential connections.
If one node has a change of state (e.g. triggered by an internal timer or triggered by some other node) it will inform other nodes (interested obsevers, see also observer pattern) about the change. Each informed node will then take appropriate actions to update its own state (and in turn inform other observers as needed). A root node will not know about every change that occurs, since only the involved nodes will know that something has changed. If such a chain of events is triggered by the root node then of course it's not much of an issue.
The aim is to assure data persistence with an object database. Data in memory should be in sync with data stored within the database. What adds to the complexity is the fact that the graphs don't consist of simple (and stupid) data nodes, but that lots of functionality is integrated in each node (i.e. events that trigger state changes throughout a graph).
I have several rough ideas on how to cope with the presented issue (e.g. (1) stronger separation of data and functionality or (2) stronger integration of the database or (3) set an arbitrary time interval to update data and accept that data may be out of synch for a period of time). I'm looking for some more input and options concerning such a key issue (which will definitely leave significant footprints on a concrete implementation).
(edited)
There is another aspect I forgot to mention. A graph should not reside all the time in memory. Graphs that are not needed will be only present in the database and thus put in a state of suspension. This is another issue which needs consideration. While in suspension the update mechanisms will probably be put to sleep as well and this is not intended.
In the case of db4o check out "transparent activation" to automatically load objects on demand as you traverse the graph (this way the graph doesn't have to be all in memory) and check out "transparent persistence" to allow each node to persist itself after a state change.
http://www.gamlor.info/wordpress/2009/12/db4o-transparent-persistence/
Moreover you can use db4o "callbacks" to trigger custom behavior during db4o operations.
HTH
German
What's the exact question? Here a few comments:
As #German already mentioned: For complex object graphs you probably want to use transparent persistence.
Also as #German mentione: Callback can help you to do additional stuff when objects are read/written etc on the database.
To the Observer-Pattern. Are you on .NET or Java? Usually you don't want to store the observers in the database, since the observers are usually some parts of your business-logic, GUI etc. On .NET events are automatically not stored. On Java make sure that you mark the field holding the observer-references as transient.
In case you actually want to store observers, for example because they are just other elements in your object-graph. On .NET, you cannot store delegates / closures. So you need to introduce a interface for calling the observer. On Java: Often we use anonymous inner classes as listener: While db4o can store those, I would NOT recommend that. Because a anonymous inner class gets generated name which can change. Then db4o will not find that class later if you've changed your code.
Thats it. Ask more detailed questions if you want to know more.
If you have a lot of small classes (that are often created and destroyed), and they all depend on the settings, how would you do that?
It would be nice not to have to connect each one to some kind of "settings changed" signal, and even if I did, all the settings will be updated, even those objects whose settings didn't change.
When faced with that myself, I've found it's better to control the save/load settings from a central place. Do you really need to save/load the settings on a regular basis or can you have a master object (likely with a list of the sub-objects) control when savings actually need to be done? Or, worst case, as the objects are created and destroyed have them update an in-memory setting map in the parent collection and save when it thinks it should be saved, rather than child object destruction.
One way of implementing it is given below.
If you wish, the central location for the settings can be a singleton derived from QAbstractItemModel, and you can easily connect the dataChanged(...) signal to various objects as necessary, to receive notifications about changed settings. Those objects can decide whether an applicable setting was changed. By judicious use of helper and shim classes, you can make it very easy to connect your "small classes" with notifications. This would address two issues inherent in the model driven approach to settings.
The possibly large number of subscribers, all receiving notifications about the settings they usually don't care about (the filtering issue).
The extra code needed to connect the subscriber with the item model, and the duplication of information as to what indices of the model are relevant (the selection issue).
Both filtering and selection can be dealt with by a shim class that receives all of the dataChanged notifications, and for each useful index maintains a list of subscribers. Only the slots of the "interested" objects would then be invoked. This class would maintain the list of subscriber-slot pairs on its own, without offering any signals for others to connect to. It'd use invokeMethod or a similar mechanism to invoke the slots.
The selection issue can be dealt with by observing that the subscriber classes will, upon initialization, query the model for initial values of all of the settings that affect their operation - that they are "interested" in. All you need is a temporary proxy model that you create for the duration of the initialization of the subscriber. The proxy model takes the QObject* instance of the caller, and records all of the model indices that were queried (passing them onto the singleton settings model). When the proxy model is finally destroyed at the return from the initialization of the subscriber class, it feeds the information about the model indices for this QObject to the singleton. A single additional call is needed to let the singleton know about the slot to call, but that's just like calling connect().
What I typically do is to create a class handling all my settings, with one instance per thread. To make it quicker to write this class, I implemented a couple of macros that let me define it like this:
L_DECLARE_SETTINGS(LSettingsTest, new QSettings("settings.ini", QSettings::IniFormat))
L_DEFINE_VALUE(QString, string1, QString("string1"))
L_DEFINE_VALUE(QSize, size, QSize(100, 100))
L_DEFINE_VALUE(double, temperature, -1)
L_DEFINE_VALUE(QByteArray, image, QByteArray())
L_END_CLASS
This class can be instantiated once per thread and then used without writing anything to the file. A particular instance of this class, returned from LSettingsTest::notifier(), emits signals when each property changes. If exposed to QML, each property work as regular Qt property and can be assigned, read and used in bindings.
I wrote more info here. This is the GitHub repo where I placed the macros.
its said that 1 ViewModel has 1 View.
1 View is for me a UserControl. What if my UserControl has different areas filled with data from different entities, do I have then several Views and need to build several ViewModels?
e.g: I display in a UserControl 3 entities: customer(listbox),order(datagrid),product(datagrid). Each of those "data areas" has add+remove buttons and textboxes to enter data.
Actually each of those "data areas" are put in its own GRID having so the posibility to set a individual datacontext.
1.) Should I now create 3 ViewModels CustomerVM,OrderVM and ProductVM?
2.) Are those 3 "data areas" seen as an own sort of separated View, although I have not put them in 3 UserControls.xaml files ???
3.) When this one UserControl is inside a TabControl`s tabpage where do I load the 3 entities related data? Inside the MainViewModel? I want to show/load that data only when the user clicks the tabheader.
No, you can do all that in the one viewmodel. The job of the viewmodel is to hold the data for the view, and if necessary transform that data so the view can consume it. There is nothing that says a viewmodel has to hold specific types of information, i.e. there are no rules that state "it may only hold customer info and not order info".
Having said that, there is also no reason why the viewmodel cannot be consumed by several different views (give them all different instances, of course) - this would show that you have a good separation of concerns between your views and viewmodel. Personally, i code my viewmodels so that they have no idea that the view exists. There is also no reason why the view has to consume everything that the viewmodel exposes, although binding a CustomerView to a CustomerOrderProductViewModel is going a little too far.
Edit: let me explain that last paragraph a little more.
Example 1: i have a new V which shows customer information, and i have an existing VM which has customer info AND order info
I would be reluctant to use this VM for this V, because while it does have the client info i need, it has too much info - i'm using the VM out of the context is was originally intended for.
Example 2: i have a VM that contains full client info, like their postal and residential address, their phone numbers, their girlfriend's names*, and a bunch of other client type info. I have a V which shows the client's name, birthday, and maybe two other properties.
I would consider using that VM for that V, this illustrates my point that the V doesn't have to show all the info contained within the VM. This concept becomes more apparent when you change the V (as in, do some maintenance and change the UI of the view, because someone has decided that they want a bunch of fields removed and now they want to represent the client's age as an image) - i can still use the same VM, and just change the V (i could use a ValueConverter to represent the age as an image, thus avoiding a change to the VM).
At what point would i stop using the current ClientViewModel, and write a new one that was more specific to the needs of the modified ClientView?
There is no clear cut answer to that - it depends on the amount of time i have available to do the changes, the amount of time available for testing, and the trade-off in complexity between using a full blown Client object for the VM, and writing a new leaner version of the Client object while still retaining the old one.
*that should be a collection of independant objects incorporated in the client object, but just work with me here it's a made up example :)