AngularJS是一款優秀的前端JS框架,已經被用于Google的多款產品當中。AngularJS有著諸多特性,最為核心的是:MVVM、模塊化、自動化雙向數據綁定、語義化標簽、依賴注入等等。
一.什么是數據雙向綁定
Angular實現了雙向綁定機制。所謂的雙向綁定,無非是從界面的操作能實時反映到數據,數據的變更能實時展現到界面。
一個最簡單的示例就是這樣:
<div ng-controller="CounterCtrl"> <span ng-bind="counter"></span> <button ng-click="counter++">increase</button></div>function CounterCtrl($scope) { $scope.counter = 1;}這個例子很簡單,每當點擊一次按鈕,界面上的數字就增加一。
二.數據雙向綁定原理
1.深入理解
實現用戶控制手機列表顯示順序的特性。動態排序可以這樣實現,添加一個新的模型屬性,把它和迭代器集成起來,然后讓數據綁定完成剩下的事情。
模板(app/index.html)
Search: <input ng-model="query">Sort by:<select ng-model="orderProp"> <option value="name">Alphabetical</option> <option value="age">Newest</option></select><ul class="phones"> <li ng-repeat="phone in phones | filter:query | orderBy:orderProp"> {{phone.name}} <p>{{phone.snippet}}</p> </li></ul>在index.html中做了如下更改:
首先,增加了一個叫做orderProp的<select>標簽,這樣用戶就可以選擇提供的兩種排序方法。

然后,在filter過濾器后面添加一個orderBy過濾器用其來處理進入迭代器的數據。orderBy過濾器以一個數組作為輸入,復制一份副本,然后把副本重排序再輸出到迭代器。
AngularJS在select元素和orderProp模型之間創建了一個雙向綁定。而后,orderProp會被用作orderBy過濾器的輸入。
什么時候數據模型發生了改變(比如用戶在下拉菜單中選了不同的順序),AngularJS的數據綁定會讓視圖自動更新。沒有任何笨拙的DOM操作。
控制器(app/js/controllers.js)
function PhoneListCtrl($scope) { $scope.phones = [ {"name": "Nexus S", "snippet": "Fast just got faster with Nexus S.", "age": 0}, {"name": "Motorola XOOM™ with Wi-Fi", "snippet": "The Next, Next Generation tablet.", "age": 1}, {"name": "MOTOROLA XOOM™", "snippet": "The Next, Next Generation tablet.", "age": 2} ]; $scope.orderProp = 'age';}修改了phones模型―― 手機的數組 ――為每一個手機記錄其增加了一個age屬性。根據age屬性來對手機進行排序。
在控制器代碼里加了一行讓orderProp的默認值為age。如果我們不設置默認值,這個模型會在用戶在下拉菜單選擇一個順序之前一直處于未初始化狀態。
現在我們該好好談談雙向數據綁定了。注意到當應用在瀏覽器中加載時,“Newest”在下拉菜單中被選中。這是因為我們在控制器中把orderProp設置成了‘age'。所以綁定在從我們模型到用戶界面的方向上起作用――即數據從模型到視圖的綁定。現在當你在下拉菜單中選擇“Alphabetically”,數據模型會被同時更新,并且手機列表數組會被重新排序。這個時候數據綁定從另一個方向產生了作用――即數據從視圖到模型的綁定。
2.原理分析
下面的原理想法實際上很基礎,可以被認為是3步走計劃:
還是有很多方法能夠實現上面的想法,有一個簡單有效的方法就是使用PubSub模式。 這個思路很簡單:我們使用數據特性來為HTML代碼進行綁定,所有被綁定在一起的JavaScript對象和DOM元素都會訂閱一個PubSub對象。只要JavaScript對象或者一個HTML輸入元素監聽到數據的變化時,就會觸發綁定到PubSub對象上的事件,從而其他綁定的對象和元素都會做出相應的變化。
3.發布者-訂閱者模式(PubSub模式)
設計該模式背后的主要動力是促進形成松散耦合。在這種模式中,并不是一個對象調用另一個對象的方法,而是一個對象訂閱另一個對象的特定活動并在狀態改變后獲得通知。訂閱者也稱為觀察者,而補觀察的對象稱為發布者或主題。當發生了一個重要的事件時,發布者將會通知(調用)所有訂閱者并且可能經常以事件對象的形式傳遞消息。
假設有一個發布者paper,它每天出版報紙及月刊雜志。訂閱者joe將被通知任何時候所發生的新聞。
該paper對象需要一個subscribers屬性,該屬性是一個存儲所有訂閱者的數組。訂閱行為只是將其加入到這個數組中。當一個事件發生時,paper將會循環遍歷訂閱者列表并通知它們。通知意味著調用訂閱者對象的某個方法。故當用戶訂閱信息時,該訂閱者需要向paper的subscribe()提供它的其中一個方法。
paper也提供了unsubscribe()方法,該方法表示從訂閱者數組(即subscribers屬性)中刪除訂閱者。paper最后一個重要的方法是publish(),它會調用這些訂閱者的方法,總而言之,發布者對象paper需要具有以下這些成員:
所有這三種方法都需要一個type參數,因為發布者可能觸發多個事件(比如同時發布一本雜志和一份報紙)而用戶可能僅選擇訂閱其中一種,而不是另外一種。
由于這些成員對于任何發布者對象都是通用的,故將它們作為獨立對象的一個部分來實現是很有意義的。那樣我們可將其復制到任何對象中,并將任意給定對象變成一個發布者。
三.用jQuery做一個簡單的實現
對于DOM事件的訂閱和發布,用jQuery實現起來是非常簡單的,接下來我們就是用Jquery比如下面:
function DataBinder( object_id ) { // Use a jQuery object as simple PubSub var pubSub = jQuery({}); // We expect a `data` element specifying the binding // in the form: data-bind-<object_id>="<property_name>" var data_attr = "bind-" + object_id, message = object_id + ":change"; // Listen to change events on elements with the data-binding attribute and proxy // them to the PubSub, so that the change is "broadcasted" to all connected objects jQuery( document ).on( "change", "[data-" + data_attr + "]", function( evt ) { var $input = jQuery( this ); pubSub.trigger( message, [ $input.data( data_attr ), $input.val() ] ); }); // PubSub propagates changes to all bound elements, setting value of // input tags or HTML content of other tags pubSub.on( message, function( evt, prop_name, new_val ) { jQuery( "[data-" + data_attr + "=" + prop_name + "]" ).each( function() { var $bound = jQuery( this ); if ( $bound.is("input, textarea, select") ) { $bound.val( new_val ); } else { $bound.html( new_val ); } }); }); return pubSub;}對于上面這個實現來說,下面是一個User模型的最簡單的實現方法:
function User( uid ) { var binder = new DataBinder( uid ), user = { attributes: {}, // The attribute setter publish changes using the DataBinder PubSub set: function( attr_name, val ) { this.attributes[ attr_name ] = val; binder.trigger( uid + ":change", [ attr_name, val, this ] ); }, get: function( attr_name ) { return this.attributes[ attr_name ]; }, _binder: binder }; // Subscribe to the PubSub binder.on( uid + ":change", function( evt, attr_name, new_val, initiator ) { if ( initiator !== user ) { user.set( attr_name, new_val ); } }); return user;}現在我們如果想要將User模型屬性綁定到UI上,我們只需要將適合的數據特性綁定到對應的HTML元素上。
// javascriptvar user = new User( 123 );user.set( "name", "Wolfgang" ); // html<input type="number" data-bind-123="name" />
這樣輸入值會自動映射到user對象的name屬性,反之亦然。到此這個簡單實現就完成了。
四.Angular實現數據雙向綁定
Angular主要通過scopes實現數據雙向綁定。AngularJS的scopes包括以下四個主要部分:
digest循環以及dirty-checking,包括watch,digest,和$apply。
Scope繼承 - 這項機制使得我們可以創建scope繼承來分享數據和事件。
對集合
主站蜘蛛池模板:
绩溪县|
丹江口市|
昭通市|
扶余县|
金沙县|
兴海县|
内江市|
会宁县|
大洼县|
武夷山市|
怀仁县|
安仁县|
桑日县|
迁西县|
本溪|
莎车县|
儋州市|
荔浦县|
南平市|
大埔县|
朝阳区|
虎林市|
阿合奇县|
云阳县|
平南县|
家居|
东辽县|
阳西县|
潮安县|
长寿区|
台江县|
金川县|
华宁县|
田阳县|
南丹县|
灵寿县|
厦门市|
阳信县|
柳江县|
玛曲县|
健康|