深入淺析AngularJS和DataModel
AngularJS 簡(jiǎn)介
AngularJS 是一個(gè) JavaScript 框架。它可通過 <script> 標(biāo)簽添加到 HTML 頁面。
AngularJS 通過 指令 擴(kuò)展了 HTML,且通過 表達(dá)式 綁定數(shù)據(jù)到 HTML。
什么是 AngularJS?
AngularJS 使得開發(fā)現(xiàn)代的單一頁面應(yīng)用程序(SPAs:Single Page Applications)變得更加容易。
AngularJS 把應(yīng)用程序數(shù)據(jù)綁定到 HTML 元素。
AngularJS 可以克隆和重復(fù) HTML 元素。
AngularJS 可以隱藏和顯示 HTML 元素。
AngularJS 可以在 HTML 元素"背后"添加代碼。
AngularJS 支持輸入驗(yàn)證。
通常,在AngularJS中使用JSON作為存儲(chǔ)數(shù)據(jù)的模型。我們可能這樣在controller中寫model:
app.controller('BookController',['$scope',function($scope){ $scope.book = { id:1, name:'', author:'', stores:[ {id:1, name:'', quantity:2}, {id:2, name:'', quantity:2}, ... ] }; }])
在視圖中也許這樣用到這個(gè)model:
<div ng-controller="BookController"> <span ng-bind="book.id"></span> <input type="text" ng-model="book.name"/> <input type="text" ng-model="book.author"/> </div>
當(dāng)我們需要從服務(wù)端獲取數(shù)據(jù)的時(shí)候,可能這樣寫:
app.controller('BookController',['$scope', '$http', function($scope, $http){ var bookId = 1; $http.get('api/books'+bookId).success(function(bookData){ $scope.book = bookData; }) $scope.deleteBook = function(){ $http.delete('api/books/' + bookId); } $scope.updateBook = function(){ $http.put('api/books/'+bookId, $scope.book); } $scope.getBookImageUrl = function(width, height){ return 'our/iamge/service' +bookId + '/width/height'; } $scope.isAvailable = function(){ if(!$scope.book.stores || $scope.book.stores.length === 0){ return false; } reutrn $scope.book.stores.some(function(store){ return store.quantity > 0; }) } }])
在視圖中可能這樣使用:
<div ng-controller="BookController"> <div ng-style="{backgroundImage: 'url('+getBookImageUrl(100,100)+')'}"></div> <span ng-bind="book.id"></span? <input type="text" ng-model="book.name"/> <input type="text" ng-model="book.author"/> is available: <span ng-bind="isAvailable() ? 'Yes' : 'No'"></span> <button ng-click="deleteBook()">Delete</button> <button ng-click="updateBook">Update</button> </div>
以上,JSON格式的model只能在BookController中使用,如何在其他controller中也可以使用呢?
--通過factory方式
app.factory('Book', ['$http', function($http){ function Book(bookData){ if(bookData){ this.setData(bookData); } } Book.prototype = { setData: function(bookData){ angular.extend(this, bookData); }, load: function(id){ var scope = this; $http.get('api/books/' + bookId).success(function(bookData){ scope.setData(bookData); }) }, delete: function(bookId){ $http.delete('api/books/' + bookId); }, update: function(bookId){ $http.put('api/books/' + bookId, this); }, getImageUrl: function(width, height){ return 'our/image/service/' + this.book.id + '/' + width + '/' + height; }, isAvailable: funciton(){ if(!this.book.stores || this.book.stores.length === 0) { return false; } return this.book.stores.some(function(store){ return store.quantity > 0; }) } } return Book; }])
以上,通過factory的方式創(chuàng)建了類似Book的一個(gè)Data Model,現(xiàn)在可以注入到controller中去了。
app.controller('BookController', ['$scope', 'Book', function($scope, Book){ $scope.book = new Book(); $scope.book.load(1); }])
在視圖中也會(huì)有相應(yīng)的變化。
<div ng-controller="BookController"> <div ng-style="{backgroundImage: 'url(' + book.getImageUrl(100, 100) + ')'}"></div> <span ng-bind="book.id"></span> <input type="text" ng-model="book.name"/> <input type="text" ng-model="book.author"/> is abailble: <span ng-bind="book.isAvailabe() ? 'Yes' : 'No'"></span> <button ng-click="book.delete()">Delete</button> <button ng-click="book.update()">Update</button> </div>
以上,多個(gè)controller可以使用同一個(gè)有關(guān)book的Data Model了,如果多個(gè)controller處理同一個(gè)有關(guān)book的Data Model呢?
app.factory('booksManager', ['$http', '$q', 'Book', function($http. $q, Book){ var booksManager = { _pool: {}, _retrieveInstance: function(bookId, bookData){ var instance = this._pool[bookId]; if(instance){ instance.setData(bookData); } else { instance = new Book(bookData); this._pool[bookId] = instance; } return instance; }, _seach: function(bookId){ reutrn this_.pool[bookId]; }, _load: function(bookId, deferred){ var scope = this; $http.get('api/books/' + bookId) .success(funciton(bookData){ var book = scope._retrieveInstance(bookData.id, bookData); deferred.resolve(book); }) .error(function(){ deferred.reject(); }) }, getBook: function(bookId){ var deferred = $q.defer(); var book = this._search(bookId); if(book){ deferred.resove(book); } else { this._load(bookId, deferred); } return deferred.promise; }, loadAllBooks: function(){ var deferred = $q.defer(); var scope = this; $http.get('api/books') .success(function(booksArray){ var books = []; booksArray.forEach(function(bookData){ var book = scope.l_retrieveInstance(bookData.id, bookData); books.push(book); }); deferred.resolve(books); }) .error(function(){ deferred.reject(); }); return deferred.promise; }, setBook: function(bookData){ var scope = this; var book = this._search(bookData.id); if(book){ book.setData(bookData); } else { book = scope._retrieveInstance(bookData); } return book; } }; return booksManager; }])
Book服務(wù)去掉load方法。
app.factory('Book', ['$http', function($http) { function Book(bookData) { if (bookData) { this.setData(bookData): } // Some other initializations related to book }; Book.prototype = { setData: function(bookData) { angular.extend(this, bookData); }, delete: function() { $http.delete('ourserver/books/' + bookId); }, update: function() { $http.put('ourserver/books/' + bookId, this); }, getImageUrl: function(width, height) { return 'our/image/service/' + this.book.id + '/width/height'; }, isAvailable: function() { if (!this.book.stores || this.book.stores.length === 0) { return false; } return this.book.stores.some(function(store) { return store.quantity > 0; }); } }; return Book; }]);
現(xiàn)在,多個(gè)controller可以使用同一個(gè)booksManager服務(wù)。
app.controller('EditableBookController',['$scope', 'booksManager', function($scope, booksManager){ booksManager.getBook(1).then(function(book){ $scope.book = book; }) }]) .controller('BooksListController',['$scope', 'booksManager', function($scope, booksManager){ booksManager.loadAllBooks().then(function(books){ $scope.books = books; }) }])
- angularjs學(xué)習(xí)筆記之雙向數(shù)據(jù)綁定
- 實(shí)例剖析AngularJS框架中數(shù)據(jù)的雙向綁定運(yùn)用
- 深入學(xué)習(xí)AngularJS中數(shù)據(jù)的雙向綁定機(jī)制
- 詳解JavaScript的AngularJS框架中的作用域與數(shù)據(jù)綁定
- angularjs自定義ng-model標(biāo)簽的屬性
- AngularJs 彈出模態(tài)框(model)
- angularjs在ng-repeat中使用ng-model遇到的問題
- AngularJS實(shí)現(xiàn)Model緩存的方式
- AngularJS基礎(chǔ) ng-model-options 指令簡(jiǎn)單示例
- AngularJS實(shí)踐之使用NgModelController進(jìn)行數(shù)據(jù)綁定
相關(guān)文章
基于angular-utils-ui-breadcrumbs使用心得(分享)
下面小編就為大家?guī)硪黄赼ngular-utils-ui-breadcrumbs使用心得(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11Angular.JS去掉訪問路徑URL中的#號(hào)詳解
最近天天都在用AngularJS,各類文檔也都看過好幾遍,但總是些編程上的事找不到優(yōu)雅的解決辦法。今天終于把AngularJS的項(xiàng)目訪問路徑URL里的#號(hào)去掉了,這個(gè)問題不見得有多難,關(guān)鍵是花多長(zhǎng)時(shí)間去理解AngularJS框架本身,下面來看看詳細(xì)介紹,需要的朋友可以參考下。2017-03-03利用Angular7開發(fā)一個(gè)Radio組件的全過程
這篇文章主要給大家介紹了關(guān)于如何利用Angular7開發(fā)一個(gè)Radio組件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Angular7具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07AngularJs Creating Services詳解及示例代碼
本文主要介紹AngularJs Creating Services的知識(shí)資料,這里整理了詳細(xì)的資料及簡(jiǎn)單示例代碼,有需要的小伙伴可以參考下2016-09-09angularjs實(shí)現(xiàn)對(duì)表單輸入改變的監(jiān)控(ng-change和watch兩種方式)
這篇文章主要介紹了angularjs通過ng-change和watch兩種方式實(shí)現(xiàn)對(duì)表單輸入改變的監(jiān)控,需要的朋友可以參考下2018-08-08AngularJS學(xué)習(xí)筆記之基本指令(init、repeat)
AngularJS 指令是擴(kuò)展的 HTML 屬性,帶有前綴 ng-。ng-app 指令初始化一個(gè) AngularJS 應(yīng)用程序。ng-init 指令初始化應(yīng)用程序數(shù)據(jù)。ng-model 指令把應(yīng)用程序數(shù)據(jù)綁定到 HTML 元素。2015-06-06Angular.js項(xiàng)目中使用gulp實(shí)現(xiàn)自動(dòng)化構(gòu)建以及壓縮打包詳解
基于流的前端自動(dòng)化構(gòu)建工具,利用gulp可以提高前端開發(fā)效率,特別是在前后端分離的項(xiàng)目中。下面這篇文章主要給大家介紹了關(guān)于在Angular.js項(xiàng)目中使用gulp實(shí)現(xiàn)自動(dòng)化構(gòu)建以及壓縮打包的相關(guān)資料,需要的朋友可以參考下。2017-07-07