I need binding the model properties to view elements directly bidirectional way automatically stay sync. If I make a change in a textbox I need run bussiness logic in the related model, and model properties changes automatically refresh the related ui elements.
Im new in Extjs, but I guess it doesnt support it, JQXB seem to be the right way, does anyone could point me a sample using JQXB with Extjs?
With jQXB it's very simple to stay in sync.
jQXB is striclty related to jQuery so I assume your needs can be satisfied only with jQXB and jQuery.(Extjs is no more required);
In your case you need only to use jQuery to catch textbox changes and then, supposing your datamodel already binded to controls via jQXB datasource, invoke doBind method to refresh controls after changing data model.
At http://www.jqxb.altervista.org you can see in demos pages that already do something like that.
At http://jqxb.codeplex.com ( Download Section) you can examples and in Documentation Section you can find other examples.
Alternatively you can post an example of what you want to obtain or write directly a post or an email on jQXB site.
regards
Related
The consensus I've found while reading articles about Backbone seems to be: don't store stuff in the view, store it in the model and then have the view listen for changes on the model.
If we're talking about a situation where we already have an obvious model-view pairing this is great. E.g., You have a User model and a UserView view. Obviously you set a model property on the view and it listens to changes on its model.
However, let's say I have a view that shows a list of stuff, and there are a couple of buttons to switch between 'list view' and 'grid view'. This is a very common convention I see in apps and websites. Whether I want 'list view' or 'grid view' isn't really relevant to the models/collections themselves; it seems very specific to the view itself.
At first I just tried using a view exactly like a model: setting a property, binding an event 'change:propertyName', and then using someView.set('propertyName'), etc.. to update it... but this didn't work.
While thinking how to approach this, I thought I remembered seeing something like this before:
var MyView = Backbone.View.extend({
...
model: Backbone.Model(),
...
});
So, unlike having, let's say, a UserModel.. we just have some 'typeless' model. Or I guess, I could actually create a new class, maybe called MyViewModel just for this... although I don't see a reason to.
This allows me to bind to the change event like I had wanted to and set view data with someView.model.set(...).
So my question is: is this a common thing that people do in Backbone for view state? Or is there a better way? Thanks.
Do you want the selected display style (list vs. grid) to be used whenever the user visits the page? If so, the simplest solution might be to store that state in localStorage, and have the view class access it directly.
If you don't need the current display style to be remembered, then maybe you don't need to store the state at all. Have the style change when a button is clicked. When the page refreshes, it returns to the default.
If your app has logged-in users with accounts, and you want their choice to persist across all devices they may be using, you need to have something like a UserModel (which has the logged-in user's info and preferences) that records their choice and saves it to the server. Your view can listen for changes on this model.
The beauty of Backbone (to me) is that there isn't a single right way to do something. These ideas are only some of the ways to can handle it.
You could also have a displayStyle property on the collection. I get this idea from sortable tables: in that case, the sort metadata is part of the collection object. When you resort the table by selecting a column heading, you change the collection's comparator and resort it. The view will be listening for the "sort" event and re-render when it occurs. You could do something similar for display style (you can create your own events by doing this.trigger('display-style') in your collection and having the view listen for that event).
Finally, however you decide to manage that state, you should think about whether this should all be one view class or multiple view classes. I think this would depend a lot on the complexity of your application. In many cases, it might be better to have, say, ProductListView and ProductGridView, instead of a single ProductView with two display styles. Splitting them into separate views might even make it easier to add other styles (ProductImageView, maybe?) in the future.
I am facing an issue. I have a collection of object with size around 22K records. I need to bind this to an select element. Binding is working fine for small collection but such a big collection is freezing UI until its bind completely.
Please suggest the best I can do here....
First thing that pops to mind is using one-way data binding. That is accomplished by appending :: in front of your HTML variables like so
{{::someVar}}
This way, angular will not include someVar in its watchers.
If that is still not enough for you then you might consider writing a special type of select for your own purposes which can use something like ClusterizeJS behind it.
ClusterizeJS allows only rendering a few elements on the screen and re-rendering on scroll such that the user will never know that not all the elements already exist in the select. Couple this with a search bar and you've got yourself a very fast select.
In general it is not wise to populate a <select> element with such a huge number of records. That applies no matter which framework you are using (although it would be especially bad with Angular and two way data binding).
Where you want the user to be able to select from a large number of options, I would recommend using an 'autocomplete' style of interface, where the user types a few characters and the client fetches options that match what they have typed so far.
For example, you could use Angular-UI select
Is it possible to disable an item from a FilteringSelect using a store?
The documentation shows an example of disabling an item, but only if HTML markup is used, and nothing is mentioned about select widgets using a datastore.
Looking at the source doesn't give any clues either.
If it matters the version of dojo used is 1.9
After viewing at the source code I notice that dijit/form/Select extends from dijit/form/_FormSelectWidget which in fact makes it possible to retrieve and disable options in a select.
dijit/form/FilteringSelect however does not extend from the same widget but rather from a normal dijit/form/MappedTextBox (because of the typing abilities). Because of this, I'm quite sure it's impossible to do it out of the box, using a store or not (I wasn't able to get it to work without a store and didn't find such an example at the reference guide).
If you really need such a feature, I would suggest looking at the code of dijit/form/FilteringSelect, dijit/form/Select and dijit/form/_FormSelectWidget and trying to extend from one (ore multiple ones) and implement these features by yourself. The only question I ask myself is that, if this functionality isn't implemented by default, there might be a reason behind it.
I'm new to Backbone.js and am having trouble figuring out the proper architecture for a model-view relationship.
I have a view that holds an input box and a model that is supposed to take the contents of that input box and send it to the server.
My issue is that I don't always have a discreet DOM event that triggers a request for the view to update the model data, such as input.change. Sometimes the code itself needs to ask the model to send updates to the server.
I've thought of three solutions to this problem so far, I'm not sure if any if them are any good though:
Update the model on the input element's keypress event
Once the view is initialized with the model, have the view update/add a function to the model called 'get_input_value()' that returns the value of the input box
Whenever the application needs to request the model to update the server, first call a function in the view that updates all of the information that the user has typed into the view to the model.
Please bear in mind that this is a simplified example. The view contains child views as well, all of which hold a number of elements that the user can manipulate, the model needs to be updated with all of this information so that it can update the server.
Any help and input is appreciated! Thanks so much!
Edit :::
Base on machineghost's response, I now see that I did not articulate this problem correctly:
There is a DOM event, but the problem is that it doesn't necessarily originate from inside the view that uses the model. It may originate from the Router or another view and be triggered by a global event handler. Additionally, there is not a 1:1 View-Model relationship. This model is used by multiple views who express the model in different ways. So in this case, it seems like the command to update the server should not go through a View, but to the model itself. If that is the case, the model must be able to say "Sync me with my views!".
But I don't know how to do this without breaking the rules and thus creating other problems with architecture...
Ok this is kind of a subjective question, so forgive me if this just seems like me spouting off my two cents. And before I even answer your question, I have to admit I'm a bit skeptical that you:
don't always have a discreet DOM event
because pretty much anything the user can do triggers an event that you can watch for. For instance, if you want to wait until a user changes a text input there's change, but also (as you noted) the various key* events, plus there's blur (which is commonly used for this sort of thing). Between the 3(+) you should always be able to respond appropriately to the user's actions. It would only be if (say) you had to save the text input's contents every 3 seconds that it would truly be independent of DOM events.
So, without knowing your particulars, I just have to point out that something smells fishy there. But anyhow, as for your actual question, here's my take on your ideas:
Update the model on the input element's keypress event
This certainly would work, but just be sure to use the view to do the actual event handling/model setting; hooking up the onKeyPress handler in the model would be a bad idea
Overall this approach seems pretty standard, and fits the Backbone paradigm.
Once the view is initialized with the model, have the view update/add a function to the model called 'get_input_value()' that returns the value of the input box
I don't quite get how this helps your problem, plus it seems to put the concerns in the wrong place: the model should (ideally) have nothing to do with the DOM.
Whenever the application needs to request the model to update the server, first call a function in the view that updates all of the information that the user has typed into the view to the model.
Is the save happening every 5 minutes or something? If not, then it's presumably happening in response to the user's actions, and you should use an event handler to respond.
However, if you truly do need to make the sync independent of user actions, I'd recommend using a custom event to manage things. In other words, in your model's sync method put something like this.trigger('preSync'). Then, every view which uses that model can bind some sort of updateMyModelValue method, ie. this.model.on('preSync', this.updateMyModelValue, this);.
This way, your model code is never directly interacting with the DOM at all; instead, it just worries about the stuff it's supposed to worry about (the data) and the views pay attention for when they need to update that data from the DOM.
Hope that helps.
* EDIT (in response to your editing of your question) *
If that is the case, the model must be able to say "Sync me with my views!".
The general Backbone way for a model to say ... well, pretty much anything to its views is through events.
(Technically you could maintain a list of a model's views in the model itself, and then iterate through that list to tell the views to do things. Backbone is even un-opinionated enough to let you do that. However, from a maintainability standpoint that seems like a terrible approach to me.)
My example of a "presync" event (above) demonstrates how you'd use this technique; comment back if any of it is unclear.
Similarly, if you have an issue of:
View A catches an event
View B needs to do something in response to that event
You basically have two options:
1) You can tightly couple the two views. Let's say have a table view that creates row views, but needs to respond to events that happen in those rows. You can pass the table itself as an option to the row when you create it (new Row({table:this})), and then when those rows need to tell their table "an event happened" they can just do this.options.table.informThatAnEventHappened(). This is a great approach if the two views are inherently related, like a table and its rows. If not, a better approach is:
2) You can use events to communicate between the views. Let's say you have a title div at the top of the page, which needs to be updated whenever a "title" text input changes ... but that text input is way down the page and doesn't conceptually have much to do with the page's title (apart from setting it). The common point between these two elements (and their views) is the data, the text of the title itself.
Now imagine that titleDivView and titleSettingInputView both share a pageTitle model. When titleSettingInputView calls this.model.set('titleText', 'newTitle'), the titleDivView can listen for this.model.on('change:titleText', ...), and re-render itself appropriately in response. In this way two totally un-connected, de-coupled views can interact with each other, without creating a tangled web of inter-related code.
And of course, if there isn't a nice convenient "change:title" event to bind to, you can always make your own, as with the custom "presync" event I described above.
I'm trying to get dropdownchecklist jquery plugin working with ko. I've wired up custom binding handler but dropdown won't populate with options. Please check my fiddle: http://jsfiddle.net/amitava82/wMH8J/11/
Appreciate your help. Thanks!
This is because you create dropdown before binding KnockoutJS. How does this dropdown work? It creates additional divs and spans which copy the content of select and create nice looking list. After that bindings are applied and they modify the select (as they should), but dropdown is not updated, because this library is kind of static, i.e. it copies the content of select only at the time of calling.
I've updated your jsFiddle so you can see temporary fix. What I mean is that it works now, the binding is applied before creating dropdown. The only problem is that changing options field in viewModel won't affect the dropdown. What you probably need to do is to use subscribe method. You have to monitor changes to options field and if they occur you have to recreate the dropdown. That's an easy way at least.
#freakish answer will work for most static content, but for anything dynamic using templates, for example if or foreach bindings, or you need to support underlying data updates, such as more checkbox options "suddenly" becoming available, it will not work.
An example of a really simple $.button binding apply which can be used to wrap the more simple jQuery calls. It's a simple matter of adding more members to controls to make them available in bindings.
The case with jQuery Dropdown Check List is a bit tricky however, since you obviously want to use the built in options handler, but you need to run $.dropdownchecklist after the options handler has run, as it creates the DOM elements that jQuery depends on. By wrapping the built in options handler, we are always called in the correct context.
In my experience of usage (our project makes use of about 10-15 custom bindings), you'll average about 10-20 lines of actual JS. If you start ballooning into +100 lines, I find it's a good idea to refactor, and rethink. I hope this helps some :-) I've been using Knockout for a few months now at a major UI implementation project at work, I've really learned alot, and I'm amazed at this stuff.