Maison > Article > interface Web > Une analyse approfondie d'AngularJS et DataModel_AngularJS
Introduction à AngularJS
AngularJS est un framework JavaScript. Il peut être ajouté aux pages HTML via la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a
AngularJS étend le HTML via des directives et lie les données au HTML via des expressions.
Qu'est-ce qu'AngularJS ?
AngularJS facilite le développement d'applications modernes à page unique (SPA : Single Page Applications).
AngularJS lie les données de l'application aux éléments HTML.
AngularJS peut cloner et répéter des éléments HTML.
AngularJS peut masquer et afficher des éléments HTML.
AngularJS peut ajouter du code "derrière" des éléments HTML.
AngularJS prend en charge la validation des entrées.
Habituellement, JSON est utilisé comme modèle de stockage des données dans AngularJS. Nous pouvons écrire le modèle dans le contrôleur comme ceci :
app.controller('BookController',['$scope',function($scope){ $scope.book = { id:1, name:'', author:'', stores:[ {id:1, name:'', quantity:2}, {id:2, name:'', quantity:2}, ... ] }; }])
Ce modèle peut être utilisé dans la vue comme ceci :
<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>
Lorsque nous avons besoin d'obtenir des données du serveur, nous pouvons écrire comme ceci :
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; }) } }])
peut être utilisé comme ceci dans une vue :
<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>
Ci-dessus, le modèle au format JSON ne peut être utilisé que dans BookController. Comment peut-il être utilisé dans d'autres contrôleurs ?
--Par méthode d'usine
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; }])
Ci-dessus, un modèle de données similaire à Book a été créé en usine, qui peut désormais être injecté dans le contrôleur.
app.controller('BookController', ['$scope', 'Book', function($scope, Book){ $scope.book = new Book(); $scope.book.load(1); }])
Il y aura également des changements correspondants dans la vue.
<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>
Comme ci-dessus, plusieurs contrôleurs peuvent utiliser le même modèle de données sur les livres. Que se passe-t-il si plusieurs contrôleurs traitent le même modèle de données sur les livres ?
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; }])
Le service Book supprime la méthode de chargement.
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; }]);
Désormais, plusieurs contrôleurs peuvent utiliser le même service booksManager.
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; }) }])