JQuery templates plugin: how to create two-way binding?

I started using the jQuery templates plugin (the one that was created by Microsoft), but now I am facing this problem: the template is designed for a bunch of forms attached to an array of objects; when I change something on one of the forms, I want the related object to be updated, and I cannot understand how to automate it.

Here's a simple example (a real life pattern and an object is much more complicated):

<!-- Template --> <script type="text/html" id="tmplTest"> <input type="text" value="${textvalue}"/> </script> <!-- object to bind --> <script type="text/javascript"> var obj = [{textvalue : "text1"},{textvalue : "text2"}] jQuery("#tmplTest").tmpl(obj) </script> 

This will populate two text fields, each of which is tied to a value from the corresponding object. Now, if I change the value in one of the text fields, I need to update the corresponding value of the data object. Any idea how to do this?

+2
source share
2 answers

The jQuery template does not actually implement two-way data binding, but another jQuery plugin developed by Microsoft does this. This Scott Guthrie post actually covers both the tmpl plugin and the Data Linking plugin. Scroll down to β€œClient Data Binding Support,” where Scott discusses in detail how the Data Linking plug-in works.

However, for two-way data binding, I find the knockoutjs extension much better and cleaner. declarative syntax keeps markup clean and custom data binding overrides allow many applications to be used. Finally, the plugin is pretty good for handling JSON from the server to the binding. Finally, knockoutjs also has bindings based on the tmpl plugin .

Good luck with your problem.

EDIT: Updated Code Example

Required Scripts:

 <script src="/Scripts/jquery-1.5.0.min.js" type="text/javascript"></script> <script src="/Scripts/jquery.tmpl.js" type="text/javascript"></script> <script src="/Scripts/knockout.js" type="text/javascript"></script> <script src="/Scripts/knockout.mapping.js" type="text/javascript"></script> 

Then here is the meat and potatoes

 <!-- div for loading the template --> <div data-bind='template: { name: "tmplTest", foreach: viewModel.list }'> </div> <!-- your template --> <script type='text/html' id='tmplTest'> <div> <span data-bind='text: textvalue, uniqueName: true'></span> <input data-bind='value: textvalue, uniqueName: true, valueUpdate:"afterkeydown"'/> </div> </script> <script type='text/javascript'> var viewModel = ko.mapping.fromJS( { list:[ { textvalue: "text1" }, { textvalue: "text2"} ] }); $(function() { ko.applyBindings(viewModel); }); </script> 
+9
source

You can write your own data link. Note I need an index to make this work, so I added my data to an array and put each into a template. If someone knows how to get an index without using each, add: jsfiddle link

 <script type="text/html" id="tmplTest"> {{each inputs}} <input type="text" class="datalink" data-key="textvalue" data-index="${$index}" value="${$value.textvalue}"/> {{/each}} </script> <div id="output"></div> $.extend(window, { data:[ {inputs: [{textvalue:"text1"},{textvalue:"text2"}]} ] }); $('#output').append($("#tmplTest").tmpl(window.data)); $('#output .datalink').live('change', function(){ // update object on change var $this = $(this), d = $this.data(); window.data[0].inputs[d.index*1][d.key] = $this.val(); console.log(window.data[0].inputs); }); 
0
source

Source: https://habr.com/ru/post/896875/


All Articles