• 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-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的方式创建了类似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-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>


    以上,多个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/

  • 相关阅读:
    c 的内存分配与释放原则: 通常应遵循“谁malloc,谁free”的原则。
    总算知道怎样从ImageMagick生成的数据转换成HICON: MagickGetImageBlob & LookupIconIdFromDirectoryEx
    收藏:Non-direct与direct ByteBuffer区别
    java NIO 直接与非直接缓冲区
    [收藏]:[算法]LRU和LFU的区别
    异步IO的并发能力:backlog的配置很重要
    ByteBuffer: 当由一个byte[]来生成一个固定不变的ByteBuffer时,使用ByteBuffer.wrap(byte[]);
    ByteBuffer的allocate与allocateDirect2013-01-11
    Windows完成端口与Linux epoll技术简介
    Java并发——Fork/Join框架与ForkJoinPool
  • 原文地址:https://www.cnblogs.com/darrenji/p/5192839.html
Copyright © 2020-2023  润新知