"Share" the right way to open the WeX5 (3)--binding mechanism

Source: Internet
Author: User

Today tidy up the binding mechanism of WeX5.

The problem of being native

Suppose we make an order system, we need to display the unit price, then we can calculate the total price according to the input quantity and show it. Using native code is also easy to implement, with the effect of:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/103206u5y9l51ax5o1psv1.gif "width= "273" height= "alt=" 103206u5y9l51ax5o1psv1.gif "/>"

The code is as follows:

<!--html code-->price: <span id= "Price" ></span><br />account:  <input type= "text"  id= "account"  value= ""  placeholder= "Please enter quantity"  /><br  />sum: <span id= "Sum" ></span>//js codevar priceNode =  document.getElementById (' price '),     accountnode = document.getelementbyid (' Account '),     sumnode = document.getelementbyid (' Sum '),     price = 100,    account = 11,    sum =  price * account;//initialization. pricenode.innertext = price;accountnode.value = account;sumnode.textcontent =  sum;//Monitor user input for  view layer Accountnode.addeventlistener (' KeyDown ', function  (e)  {     window.settimeout (function  ()  {        account  = accountNode.value;        sum = price *  account;        sumnode.textcontent = sum;     },10);});

Yes, it's pretty simple! Oh, by the way, we're showing 50 items at a time, and there are 10 types of such displays, as well as a variety of promotions to buy 5 boxes of Okamoto to send a fried dough stick ...

So, you know the problem with native implementations:

With the increase of UI and data interaction, the code volume grows rapidly and is difficult to maintain

Based on DOM queries, ID or class naming is difficult to manage

Code coupling is high and difficult to reuse

The solution of WeX5

In order to solve these problems, WeX5 introduced the KNOCKOUTJS (hereinafter referred to as KO) this MVVM library.

Why choose Ko rather than angular a more comprehensive framework? Angular is good, but such a chatty frame, without enough actual combat test, a lot of pits will not be exposed. Ko is a lightweight MVVM library that focuses on implementing data-to-view bindings, which in itself do not provide the functionality of UI classes and routing, so it is very simple and stable. At the same time, because he has been out for some years, now is a more mature framework. Therefore, when doing some mobile page development, Ko is undoubtedly a better choice. In addition, about the MVVM of the small tomato is not much to say, a picture to cover:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/103237g824tjnjnqej6kn9.png "width= "448" height= "215" alt= "103237g824tjnjnqej6kn9.png"/>

Ko is built on top of 3 core features (website introduction):

1. Observable objects and dependency tracking (observables and dependency tracking): Use observable objects to establish a chain of implicit relationships between model data for data transformation and binding.

2. Declarative binding (declarative bindings): Easily bind model data to DOM elements with simple, easy-to-read syntax.

3. Template (Templating): Built-in template engine, quickly write complex UI presentation for your model data.

Here is a brief talk about KO's major concepts:

Observable objects

Use Ko to rewrite the above example (custom price, which is one of my childhood wishes):

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/103250hhlcngfjocszbfdo.gif "width= "271" height= "alt=" 103250hhlcngfjocszbfdo.gif "/>"

The code is this:

<!--html code--><div id= "one" >    price: <input type= " Text " data-bind=" Value: price " placeholder=" Please enter the unit price " /><br />     account: <input type= "text"  data-bind= "Value: account"  placeholder= " Please enter the number " /><br />    sum: <span data-bind=" Text: sum " ></span></div>// js codevar viewmodel = function (P, a)  {     //is set to observable and initializes     this.price = ko.observable with parameters P, a (p);     this.account = ko.observable (a);     //call the KO function when this is passed in, Otherwise, this is Ko,ko.price () error when executing ko.purecomputed internal code.     this.sum = ko.purecomputed (function ()  {         //because the observable object is a function object, you use  price () to read the current value.      &nbsThe p;  //setting value uses Price (NewValue), which supports chained notation: This.price. Account (3)          return this.price ()  * this.account ();     }, this);}; Var vm = new viewmodel (135, 10);//Apply the binding, the binding begins to take effect ko.applybindings (VM);

1) Look at the HTML code First :

You can see that a key-value pair such as Data-bind = "Xx:oo" is added to each label. This is the binding grammar of Ko, what does xxoo represent? (Xxoo?) The little tomato is still a child ... You can see from the example that XX is a label attribute, which can be a tag attribute such as text, value, class, checked, and so on, which can actually be a DOM event such as click, Focus, load, and so on. OO looks like a variable, not actually a variable, but rather a function object that executes the function (with a ()) to get the corresponding binding value. By Xxoo, you can bind the attributes or events of an element with the function object in JS (Xxoo will be responsible for each other?), which is the declarative binding of KO. The definition of a binding is actually an observer pattern, but this is a two-way binding, where publishers and subscribers subscribe to each other's messages, which is the two-way binding of MVVM. The result of Ko bidirectional binding is that one change can automatically update the other, that is, the data and the presentation layer are tightly bound together by ViewModel. The effect of binding is similar to:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/103306ztyaay2kkzbbkmmr.gif "width= "187" height= "228" alt= "103306ztyaay2kkzbbkmmr.gif"/>

2) Look at the JS code again:

You can see that a ViewModel object is defined in JS, and the object is manipulated in the HTML bound oo. There are two main operations: Ko.observable () and ko.purecomputed ().

    • Ko.observable (p): See the name, this is the way to set the observable object, The passed-in parameter p is the initialized value, where the argument can be either a basic data type or a JSON object. Being set as an observable means that the system will always observe this value. Either p in the ViewModel or P in the bound object will cause a refresh event, updating all the places where this value is used to the latest state. It is obvious that observable objects are more consumable, so do not set as observable for values that do not require dynamic changes (such as prices), or you need to put them in viewmodel for centralized initialization.

    • Note: The observable object returned by Ko.observable (p) is a function object, so it is necessary to read the observable object using price (), and similarly, to set the observable object to use the price (NewValue) method. More intimate is that when set up to support the chain style: Viewmodel.price. Account (10).

    • ko.purecomputed () is the so-called dependency tracking, here is the unit price * Quantity equals the total price, note here can not directly use This.sum = This.price () * This.account (); To specify SUM, This notation does not dynamically refresh the bound object, but it changes the sum variable dynamically, but other actions are required to flush the bound object. Therefore, the calculation-related binding values are set using KO's calculation function. Of course, the return is also a function object. In addition, KO has a computed function, which can also be set, but it is recommended to use pure to improve performance.

    • Note the wording here: ko.purecomputed (FN, this), which is to bind FN to the ViewModel execution environment, is actually the call/apply in JS. Because this is a KO object in the execution of the KO intrinsic function, it is required to pass the above notation in order to get the ViewModel object. Of course, you can also save the ViewModel object with that outside of the KO function, and then use that within the KO function to invoke the ViewModel object. Like this:

var that = This;this.sum = ko.purecomputed (function () {return That.price () * That.account ();});

Once you have defined the ViewModel constructor, you instantiate a ViewModel object, and then use the Ko.applybindings () method to make the binding effective, and do not miss the step.

Simple mode using KO's page:

<!--HTML Code--><span data-bind= "Text:bindtext" ></span>//js codevar viewModel = {Bindtext:ko.obse Rvable (' InitValue ')};ko.applybindings (ViewModel);

Summed up is: HTML using data-bind= "Xx:oo" declaration binding, JS set up ViewModel and set the observable object, finally apply the binding.

Observable array of objects

Then look at the use of the observable object array, in KO can not be like JS as the array and variables mixed, for the array object will be used Ko.observablearray ([...,...]) In this form, as well, the array element can also be a basic type or a JSON object. The array of observable objects in Ko has a series of array manipulation methods, such as slice (), sort (), push (), the effect is the same as the native JS array operation method, only the changes made by the Ko method will notify subscribers to refresh the interface, but the JS method will not refresh the interface. Here is a simple example:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/103322s8gt74t59txr99zg.gif "width= "141" height= "alt="/> "103322s8gt74t59txr99zg.gif"

<!--HTML code--><select data-bind= "options:list" ></select>//js codevar vm = {//LIST:KO.OBSERVABL Earray () List:ko.observableArray ([' Luffy ', ' Zoro ', ' Sanji '])};ko.applybindings (VM);

Key point: KO monitors the state of the array, not the state of the element itself. This means that when the array state changes (adding or subtracting elements), the KO event is triggered to cause a flush of the bound object, but changes in the inner elements of the array (e.g., value changes) are not monitored to trigger the KO event. For example:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/103336pywv2vu2rgyw22yt.gif "width= "390" height= "163" alt= "103336pywv2vu2rgyw22yt.gif"/>

Using the native method in the console to change the Luffy dynamic to Lucy is not refreshing the UI page, while the array operation using KO changes the array will immediately refresh the page, it is worth noting that at the time of the refresh, will also refresh the previous changes (Luffy > Lucy). In other words, JS memory variables are changed, but there is a lack of a refreshing dom action. As you can see here, the way to read an array is vm.list () [0], because list is also a function object, and executing the return value is the list content we want. Similarly, you can reset the array of observable objects in such a way that vm.list (["Sister", "sister", "sister"]), and refresh the UI immediately.

If you need to dynamically react to changes in the array elements to the UI, you need to set the array elements as observable objects, and then use Ko's method to change the values of the array elements. Note that is the method of using KO list () [0] ("Lucy")!

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/103404ea18pcp7zolufw17.gif "width= "391" height= "158" alt= "103404ea18pcp7zolufw17.gif"/>

There are two ways to manipulate an array of observable objects, one with the same name as the native JS array: Pop, push, shift, unshift, reverse, sort, splice, this part is the same as the use and effect of the JS native method, which is no longer mentioned.

Some of the other methods are not in JS, mainly have the following several:

Remove (Someitem)-Removes all element items with values equal to Someitem and returns them as an array, meaning that you cannot delete the first item directly list.remove (0), but instead use the List.remove (list () [0] ) This form to remove. All in all, the parameter passed in must be the value of the element item, either in the form of list () [0] or directly into a string of values (such as "Luffy").

Remove (function (item) {return Item.age < 18;})--Removes all element items with an age attribute less than 18 and returns them as an array, which is no different from the usual array higher order functions. Item is passed as a parameter to the higher-order function, and when the array is traversed, the item is deleted when the return value of the higher-order function is true, otherwise it goes to the next item.

RemoveAll ([' Chad ', undefined])--Removes all element items that have the same value as ' Chad ' or 123 or undefined and returns them as an array.

RemoveAll ()--Deletes all items and returns as an array.

Tip: When working with observable objects, you can use extended Myobservablearray.extend ({ratelimit:1000}) to set up deferred refreshes when the number of objects is large and the interaction is frequent, and each change is immediately refreshed. For example, when inserting elements into an observable array, you can set a cycle time of 1000ms, and let all operations within 1000ms be concentrated into a single flush, avoiding the performance deterioration caused by the frequent manipulation of the DOM.

How to use KO in WeX5?

WeX5 as a leader in the HTML5 development tool world, and without the integration of the excellent KO Framework, the method used is very simple: Specify the bind attribute of the component in the visual editor and then manipulate the corresponding bound value in the JS code.

First specify in the visual editor:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/102843sqzdsetp25mzmyd1.png "width= "312" height= "281" alt= "102843sqzdsetp25mzmyd1.png"/>650) this.width=650; "Src=" http://bbs.wex5.com/data/ Attachment/forum/201606/29/102848eyzds1shuczhr3hy.png "width=" "height=" 286 "alt=" 102848eyzds1shuczhr3hy.png "/ >

This method in the Hello World also has a brief introduction, unfamiliar classmate can go to see Kazakhstan first. With the visual editor we can bind the corresponding property or event, here we bind a string "Hello World" for Bind-ref, and other properties and events will be described in the next article. After binding we open the Code Editor and found that there is no 1 in the same binding code. Where did the binding code go? Please open the HTML source code:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/102854ryzvs7ogxahp9r4o.png "width= "625" height= "263" alt= "102854ryzvs7ogxahp9r4o.png"/>

You can see the "Bind-ref= ' Hello World" appears in the code, is it similar to the one mentioned above Data-bind? Here WeX5 add the properties that each component can bind to the visual editor, so that you don't have to remember what properties a component can tie, and where the mouse is tied! Of course, the binding string doesn't make much sense, and we usually bind a variable (actually a function object that returns a value of the desired variable). For example:

650) this.width=650; "src=" Http://bbs.wex5.com/data/attachment/forum/201606/29/102859b87g666b6tqd7607.png "width= "247" height= "252" alt= "102859b87g666b6tqd7607.png"/>

Here the text is bound to mytext, this form of binding is directly tied to the model object, so you can in the JS source model under the operation of this MyText object.

1 define (function (require) {2 var $ = require ("jquery");  3 var justep = require ("$UI/system/lib/justep");  4 5 var Model = function () {6 this.callparent (); 7 This.mytext = Justep.  Bind.observable ("bind!");  8}; 9 Model.prototype.button2Click = function (event) {This.myText.set ("changed"); 11}; return Model; 13}); 14

You can see that the KO component has been encapsulated into the Justep bind object, and the operation of the observable object is a bit different from the KO, where the set/get is used to set and get the values of the observable objects respectively. The use of other methods, such as compute, is consistent with that of KO.

Summarize

This article briefly introduces the origins of data binding in WEX5 and the excellent framework behind it (Knockoutjs), highlighting the most important concepts in KO: observable objects (arrays), and then simply demonstrates how to use binding mechanisms in WeX5 and the differences between bindings in WeX5 and Ko.

A brief introduction to observable objects is here, and the next article will describe the usage of various bindings! The code word is not easy, at the same point likes ha ~

Resources:

1. Ko's official tutorial: http://knockoutjs.com/documentation/introduction.html

2. WeX5 Binding Tutorial: http://docs.wex5.com/data-bind-instro/


"Share" the right way to open the WeX5 (3)--binding mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.