你的位置:首页 > Java教程

[Java教程]AngularJS和DataModel


 

通常,在AngularJS中使用JSON作为存储数据的模型。我们可能这样在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},      ...    ]  };}])

 

在视图中也许这样用到这个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>

 


当我们需要从服务端获取数据的时候,可能这样写:

 

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-></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的方式创建了类似Book的一个Data Model,现在可以注入到controller中去了。

 

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

 

在视图中也会有相应的变化。

 

<div ng-controller="BookController">  <div ng-></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>

 


以上,多个controller可以使用同一个有关book的Data Model了,如果多个controller处理同一个有关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服务去掉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;}]);

 


现在,多个controller可以使用同一个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;    })  }])

 

参考:http://www.webdeveasy.com/angularjs-data-model/