自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

AngularJS數(shù)據(jù)建模

開發(fā) 前端
我們知道,AngularJS并沒有自帶立等可用的數(shù)據(jù)建模方案。而是以相當(dāng)抽象的方式,讓我們?cè)赾ontroller中使用JSON數(shù)據(jù)作為模 型。但是隨著時(shí)間的推移和項(xiàng)目的成長,我意識(shí)到這種建模的方式不再能滿足我們項(xiàng)目的需求。在這篇文章中我會(huì)介紹在我的AngularJS應(yīng)用中處理數(shù)據(jù)建 模的方式。

我們知道,AngularJS并沒有自帶立等可用的數(shù)據(jù)建模方案。而是以相當(dāng)抽象的方式,讓我們?cè)赾ontroller中使用JSON數(shù)據(jù)作為模 型。但是隨著時(shí)間的推移和項(xiàng)目的成長,我意識(shí)到這種建模的方式不再能滿足我們項(xiàng)目的需求。在這篇文章中我會(huì)介紹在我的AngularJS應(yīng)用中處理數(shù)據(jù)建 模的方式。

為Controller定義模型

讓我們從一個(gè)簡單的例子開始。我想要顯示一個(gè)書本(book)的頁面。下面是控制器(Controller):

BookController

  1. app.controller('BookController', ['$scope'function($scope) { 
  2.     $scope.book = { 
  3.         id: 1, 
  4.         name: 'Harry Potter'
  5.         author: 'J. K. Rowling'
  6.         stores: [ 
  7.             { id: 1, name: 'Barnes & Noble', quantity: 3}, 
  8.             { id: 2, name: 'Waterstones', quantity: 2}, 
  9.             { id: 3, name: 'Book Depository', quantity: 5} 
  10.         ] 
  11.     }; 
  12. }]); 

這個(gè)控制器創(chuàng)建了一個(gè)書本的模型,我們可以在后面的模板中(templage)中使用它。

template for displaying a book

  1. <div ng-controller="BookController"> 
  2.     Id: <span ng-bind="book.id"></span> 
  3.       
  4.     Name:<input type="text" ng-model="book.name" /> 
  5.       
  6.     Author: <input type="text" ng-model="book.author" /> 
  7. </div> 
假如我們需要從后臺(tái)的api獲取書本的數(shù)據(jù),我們需要使用$http:

BookController with $http

  1. app.controller('BookController', ['$scope''$http'function($scope, $http) { 
  2.     var bookId = 1; 
  3.   
  4.     $http.get('ourserver/books/' + bookId).success(function(bookData) { 
  5.         $scope.book = bookData; 
  6.     }); 
  7. }]); 

注意到這里的bookData仍然是一個(gè)JSON對(duì)象。接下來我們想要使用這些數(shù)據(jù)做一些事情。比如,更新書本信息,刪除書本,甚至其他的一些不涉及到后臺(tái)的操作,比如根據(jù)請(qǐng)求的圖片大小生成一個(gè)書本圖片的url,或者判斷書本是否有效。這些方法都可以被定義在控制器中。

BookController with several book actions

  1. app.controller('BookController', ['$scope''$http'function($scope, $http) { 
  2.     var bookId = 1; 
  3.   
  4.     $http.get('ourserver/books/' + bookId).success(function(bookData) { 
  5.         $scope.book = bookData; 
  6.     }); 
  7.   
  8.     $scope.deleteBook = function() { 
  9.         $http.delete('ourserver/books/' + bookId); 
  10.     }; 
  11.   
  12.     $scope.updateBook = function() { 
  13.         $http.put('ourserver/books/' + bookId, $scope.book); 
  14.     }; 
  15.   
  16.     $scope.getBookImageUrl = function(width, height) { 
  17.         return 'our/image/service/' + bookId + '/width/height'
  18.     }; 
  19.   
  20.     $scope.isAvailable = function() { 
  21.         if (!$scope.book.stores || $scope.book.stores.length === 0) { 
  22.             return false
  23.         } 
  24.         return $scope.book.stores.some(function(store) { 
  25.             return store.quantity > 0; 
  26.         }); 
  27.     }; 
  28. }]); 

然后在我們的模板中:

template for displaying a complete book

  1. <div ng-controller="BookController"
  2.     <div ng-style="{ backgroundImage: 'url(' + getBookImageUrl(100, 100) + ')' }"></div> 
  3.     Id: <span ng-bind="book.id"></span> 
  4.       
  5.     Name:<input type="text" ng-model="book.name" /> 
  6.       
  7.     Author: <input type="text" ng-model="book.author" /> 
  8.       
  9.     Is Available: <span ng-bind="isAvailable() ? 'Yes' : 'No' "></span> 
  10.       
  11.     <button ng-click="deleteBook()">Delete</button> 
  12.       
  13.     <button ng-click="updateBook()">Update</button> 
  14. </div> 

#p#

在controllers之間共享Model

如果書本的結(jié)構(gòu)和方法只和一個(gè)控制器有關(guān),那我們現(xiàn)在的工作已經(jīng)可以應(yīng)付。但是隨著應(yīng)用的增長,會(huì)有其他的控制器也需要和書本打交道。那些控制器很 多時(shí)候也需要獲取書本,更新它,刪除它,或者獲得它的圖片url以及看它是否有效。因此,我們需要在控制器之間共享這些書本的行為。我們需要使用一個(gè)返回 書本行為的factory來實(shí)現(xiàn)這個(gè)目的。在動(dòng)手寫一個(gè)factory之前,我想在這里先提一下,我們創(chuàng)建一個(gè)factory來返回帶有這些book輔助 方法的對(duì)象,但我更傾向于使用prototype來構(gòu)造一個(gè)Book類,我覺得這是更正確的選擇:

Book model service

  1. app.factory('Book', ['$http'function($http) { 
  2.     function Book(bookData) { 
  3.         if (bookData) { 
  4.             this.setData(bookData): 
  5.         } 
  6.         // Some other initializations related to book 
  7.     }; 
  8.     Book.prototype = { 
  9.         setData: function(bookData) { 
  10.             angular.extend(this, bookData); 
  11.         }, 
  12.         load: function(id) { 
  13.             var scope = this
  14.             $http.get('ourserver/books/' + bookId).success(function(bookData) { 
  15.                 scope.setData(bookData); 
  16.             }); 
  17.         }, 
  18.         deletefunction() { 
  19.             $http.delete('ourserver/books/' + bookId); 
  20.         }, 
  21.         update: function() { 
  22.             $http.put('ourserver/books/' + bookId, this); 
  23.         }, 
  24.         getImageUrl: function(width, height) { 
  25.             return 'our/image/service/' + this.book.id + '/width/height'
  26.         }, 
  27.         isAvailable: function() { 
  28.             if (!this.book.stores || this.book.stores.length === 0) { 
  29.                 return false
  30.             } 
  31.             return this.book.stores.some(function(store) { 
  32.                 return store.quantity > 0; 
  33.             }); 
  34.         } 
  35.     }; 
  36.     return Book; 
  37. }]); 

這種方式下,書本相關(guān)的所有行為都被封裝在Book服務(wù)內(nèi)?,F(xiàn)在,我們?cè)贐ookController中來使用這個(gè)亮眼的Book服務(wù)。

BookController that uses Book model

  1. app.controller('BookController', ['$scope''Book'function($scope, Book) { 
  2.     $scope.book = new Book(); 
  3.     $scope.book.load(1); 
  4. }]); 

正如你看到的,控制器變得非常簡單。它創(chuàng)建一個(gè)Book實(shí)例,指派給scope,并從后臺(tái)加載。當(dāng)書本被加載成功時(shí),它的屬性會(huì)被改變,模板也隨著 被更新。記住其他的控制器想要使用書本功能,只要簡單地注入Book服務(wù)即可。此外,我們還要改變template使用book的方法。

template that uses book instance

  1. <div ng-controller="BookController"> 
  2.     <div ng-style="{ backgroundImage: 'url(' + book.getImageUrl(100, 100) + ')' }"></div> 
  3.     Id: <span ng-bind="book.id"></span> 
  4.       
  5.     Name:<input type="text" ng-model="book.name" /> 
  6.       
  7.     Author: <input type="text" ng-model="book.author" /> 
  8.       
  9.     Is Available: <span ng-bind="book.isAvailable() ? 'Yes' : 'No' "></span> 
  10.       
  11.     <button ng-click="book.delete()">Delete</button> 
  12.       
  13.     <button ng-click="book.update()">Update</button> 
  14. </div> 

到這里,我們知道了如何建模一個(gè)數(shù)據(jù),把他的方法封裝到一個(gè)類中,并且在多個(gè)控制器中共享它,而不需要寫重復(fù)代碼。

在多個(gè)控制器中使用相同的書本模型

我們定義了一個(gè)書本模型,并且在多個(gè)控制器中使用了它。在使用了這種建模架構(gòu)之后你會(huì)注意到有一個(gè)嚴(yán)重的問題。到目前為止,我們假設(shè)多個(gè)控制器對(duì)書本進(jìn)行操作,但如果有兩個(gè)控制器同時(shí)處理同一本書會(huì)是什么情況呢?

假設(shè)我們頁面的一塊區(qū)域我們所有書本的名稱,另一塊區(qū)域可以更新某一本書。對(duì)應(yīng)這兩塊區(qū)域,我們有兩個(gè)不同的控制器。***個(gè)加載書本列表,第二個(gè)加 載特定的一本書。我們的用戶在第二塊區(qū)域中修改了書本的名稱并且點(diǎn)擊“更新”按鈕。更新操作成功后,書本的名稱會(huì)被改變。但是在書本列表中,這個(gè)用戶始終 看到的是修改之前的名稱!真實(shí)的情況是我們對(duì)同一本書創(chuàng)建了兩個(gè)不同的書本實(shí)例——一個(gè)在書本列表中使用,而另一個(gè)在修改書本時(shí)使用。當(dāng)用戶修改書本名稱 的時(shí)候,它實(shí)際上只修改了后一個(gè)實(shí)例中的屬性。然而書本列表中的書本實(shí)例并未得到改變。

解決這個(gè)問題的辦法是在所有的控制器中使用相同的書本實(shí)例。在這種方式下,書本列表和書本修改的頁面和控制器都持有相同的書本實(shí)例,一旦這個(gè)實(shí)例發(fā) 生變化,就會(huì)被立刻反映到所有的視圖中。那么按這種方式行動(dòng)起來,我們需要?jiǎng)?chuàng)建一個(gè)booksManager服務(wù)(我們沒有大寫開頭的b字母,是因?yàn)檫@是 一個(gè)對(duì)象而不是一個(gè)類)來管理所有的書本實(shí)例池,并且富足返回這些書本實(shí)例。如果被請(qǐng)求的書本實(shí)例不在實(shí)例池中,這個(gè)服務(wù)會(huì)創(chuàng)建它。如果已經(jīng)在池中,那么 就直接返回它。請(qǐng)牢記,所有的加載書本的方法最終都會(huì)被定義在booksManager服務(wù)中,因?yàn)樗俏ㄒ坏奶峁緦?shí)例的組件。

#p#

booksManager service

  1. app.factory('booksManager', ['$http''$q''Book'function($http, $q, Book) { 
  2.     var booksManager = { 
  3.         _pool: {}, 
  4.         _retrieveInstance: function(bookId, bookData) { 
  5.             var instance = this._pool[bookId]; 
  6.   
  7.             if (instance) { 
  8.                 instance.setData(bookData); 
  9.             } else { 
  10.                 instance = new Book(bookData); 
  11.                 this._pool[bookId] = instance; 
  12.             } 
  13.   
  14.             return instance; 
  15.         }, 
  16.         _search: function(bookId) { 
  17.             return this._pool[bookId]; 
  18.         }, 
  19.         _load: function(bookId, deferred) { 
  20.             var scope = this
  21.   
  22.             $http.get('ourserver/books/' + bookId) 
  23.                 .success(function(bookData) { 
  24.                     var book = scope._retrieveInstance(bookData.id, bookData); 
  25.                     deferred.resolve(book); 
  26.                 }) 
  27.                 .error(function() { 
  28.                     deferred.reject(); 
  29.                 }); 
  30.         }, 
  31.         /* Public Methods */ 
  32.         /* Use this function in order to get a book instance by it's id */ 
  33.         getBook: function(bookId) { 
  34.             var deferred = $q.defer(); 
  35.             var book = this._search(bookId); 
  36.             if (book) { 
  37.                 deferred.resolve(book); 
  38.             } else { 
  39.                 this._load(bookId, deferred); 
  40.             } 
  41.             return deferred.promise; 
  42.         }, 
  43.         /* Use this function in order to get instances of all the books */ 
  44.         loadAllBooks: function() { 
  45.             var deferred = $q.defer(); 
  46.             var scope = this
  47.             $http.get('ourserver/books) 
  48.                 .success(function(booksArray) { 
  49.                     var books = []; 
  50.                     booksArray.forEach(function(bookData) { 
  51.                         var book = scope._retrieveInstance(bookData.id, bookData); 
  52.                         books.push(book); 
  53.                     }); 
  54.   
  55.                     deferred.resolve(books); 
  56.                 }) 
  57.                 .error(function() { 
  58.                     deferred.reject(); 
  59.                 }); 
  60.             return deferred.promise; 
  61.         }, 
  62.         /*  This function is useful when we got somehow the book data and we wish to store it or update the pool and get a book instance in return */ 
  63.         setBook: function(bookData) { 
  64.             var scope = this
  65.             var book = this._search(bookData.id); 
  66.             if (book) { 
  67.                 book.setData(bookData); 
  68.             } else { 
  69.                 book = scope._retrieveInstance(bookData); 
  70.             } 
  71.             return book; 
  72.         }, 
  73.   
  74.     }; 
  75.     return booksManager; 
  76. }]); 

下面是我們的EditableBookController和BooksListController兩個(gè)控制器的代碼:

EditableBookController and BooksListController that uses booksManager

  1. app.factory('Book', ['$http'function($http) { 
  2.     function Book(bookData) { 
  3.         if (bookData) { 
  4.             this.setData(bookData): 
  5.         } 
  6.         // Some other initializations related to book 
  7.     }; 
  8.     Book.prototype = { 
  9.         setData: function(bookData) { 
  10.             angular.extend(this, bookData); 
  11.         }, 
  12.         deletefunction() { 
  13.             $http.delete('ourserver/books/' + bookId); 
  14.         }, 
  15.         update: function() { 
  16.             $http.put('ourserver/books/' + bookId, this); 
  17.         }, 
  18.         getImageUrl: function(width, height) { 
  19.             return 'our/image/service/' + this.book.id + '/width/height'
  20.         }, 
  21.         isAvailable: function() { 
  22.             if (!this.book.stores || this.book.stores.length === 0) { 
  23.                 return false
  24.             } 
  25.             return this.book.stores.some(function(store) { 
  26.                 return store.quantity > 0; 
  27.             }); 
  28.         } 
  29.     }; 
  30.     return Book; 
  31. }]); 

需要注意的是,模塊(template)中還是保持原來使用book實(shí)例的方式?,F(xiàn)在應(yīng)用中只持有一個(gè)id為1的book實(shí)例,它發(fā)生的所有改變都會(huì)被反映到使用它的各個(gè)頁面上。

總結(jié)

在這片文章中,我建議了AngularJS中建模數(shù)據(jù)的一種架構(gòu)。首先,我展示了AngularJS默認(rèn)的數(shù)據(jù)模型綁定,然后講了如何封裝模型的方 法和操作從而可以在不同的控制其中重用它們,***我解釋了如何管理模型實(shí)例從而使得所有的改變都能被反映到應(yīng)用中各個(gè)相關(guān)的視圖上。

希望這篇文章能在如何實(shí)現(xiàn)數(shù)據(jù)建模上給你一些啟示。

原文鏈接:http://www.webdeveasy.com/angularjs-data-model/

譯文鏈接:http://blog.jobbole.com/54817/

責(zé)任編輯:陳四芳 來源: 伯樂在線
相關(guān)推薦

2020-10-10 06:53:18

數(shù)據(jù)建模數(shù)據(jù)庫

2012-07-26 08:32:38

MongoDB

2012-05-15 10:28:29

NoSQL數(shù)據(jù)庫建模技術(shù)

2017-02-05 14:59:18

MongoDB數(shù)據(jù)建模數(shù)據(jù)庫

2012-05-15 11:03:22

NoSQL數(shù)據(jù)建模

2016-05-10 10:43:02

2021-07-30 18:35:57

數(shù)據(jù)建模聚類

2023-08-14 16:56:53

2014-03-12 10:22:59

AngularJS指令

2014-05-30 10:51:55

PhpStormAngularJS

2010-06-30 16:29:29

UML數(shù)據(jù)建模

2024-01-10 08:22:38

物聯(lián)網(wǎng)數(shù)據(jù)分析建模人工智能

2019-09-27 12:44:03

數(shù)據(jù)建模企業(yè)數(shù)據(jù)存儲(chǔ)

2021-08-26 23:01:41

人工智能氣候大數(shù)據(jù)

2010-06-30 16:52:23

UML數(shù)據(jù)建模

2019-08-01 13:09:57

大數(shù)據(jù)分析建模信息化

2014-07-11 09:24:56

終端調(diào)試AngularJS

2016-02-26 15:22:15

AngularJS

2009-01-18 16:01:42

數(shù)據(jù)倉庫數(shù)據(jù)建模常用術(shù)語

2016-09-16 23:21:51

數(shù)據(jù)分析數(shù)據(jù)建模
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)