深入浅析AngularJS和DataModel

AngularJS 简介

AngularJS 是一个 JavaScript 框架。它可通过 <script> 标签添加到 HTML 页面。

AngularJS 通过 指令 扩展了 HTML,且通过 表达式 绑定数据到 HTML。

什么是 AngularJS?

AngularJS 使得开发现代的单一页面应用程序(SPAs:Single Page Applications)变得更加容易。

AngularJS 把应用程序数据绑定到 HTML 元素。

AngularJS 可以克隆和重复 HTML 元素。

AngularJS 可以隐藏和显示 HTML 元素。

AngularJS 可以在 HTML 元素"背后"添加代码。

AngularJS 支持输入验证。

通常,在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;
})
}])
(0)

相关推荐

  • 实例剖析AngularJS框架中数据的双向绑定运用

    数据绑定 通过把一个文本输入框绑定到person.name属性上,就能把我们的应用变得更有趣一点.这一步建立起了文本输入框跟页面的双向绑定. 在这个语境里"双向"意味着如果view改变了属性值,model就会"看到"这个改变,而如果model改变了属性值,view也同样会"看到"这个改变.Angular.js 为你自动搭建好了这个机制.如果你好奇这具体是怎么实现的,请看我们之后推出的一篇文章,其中深入讨论了digest_loop 的运作. 要建立

  • AngularJS实现Model缓存的方式

    在AngularJS中如何实现一个Model的缓存呢? 可以通过在Provider中返回一个构造函数,并在构造函数中设计一个缓存字段,在本篇末尾将引出这种做法. 一般来说,Model要赋值给Scope的某个变量. 有的直接把对象赋值给Scope变量:有的在Provider中返回一个对象再赋值给Scope变量:有的在Provider中返回一个构造函数再赋值给Scope变量.本篇来一一体验. 首先自定义一个directive,用来点击按钮改变一个scope变量值. angular .module('

  • angularjs自定义ng-model标签的属性

    有的时候我们需要为非input类型的元素添加ng-model来实现双向的数据绑定,从而减少冗余代码,那么可以尝试一下的方式 例如:我页面中使用了contenteditable这个属性来实现用户可直接编译的div元素 html: <style> .text{ margin:0 auto; width:100px; height:50px; border:1px solid red; } </style> </head> <body> <div ng-co

  • AngularJS实践之使用NgModelController进行数据绑定

    前言 在Angular应用中,ng-model指令时不可缺少的一个部分,它用来将视图绑定到数据,是双向绑定魔法中重要的一环.ngModelController则是ng-model指令中所定义的controller.这个controller包含了一些用于数据绑定,验证,CSS更新,以及数值格式化和解析的服务.它不用来进行DOM渲染或者监听DOM事件.与DOM相关的逻辑都应该包含在其他的指令中,然后让这些指令来试用ngModelController中的数据绑定功能. 注意:本篇文章不是对NgMode

  • AngularJS基础 ng-model-options 指令简单示例

    AngularJS ng-model-options 指令 AngularJS 实例 在失去焦点时绑定输入框的值到 scope 变量中: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></scrip

  • 深入学习AngularJS中数据的双向绑定机制

    Angular JS (Angular.JS) 是一组用来开发Web页面的框架.模板以及数据绑定和丰富UI组件.它支持整个开发进程,提供web应用的架构,无需进行手工DOM操作. AngularJS很小,只有60K,兼容主流浏览器,与 jQuery 配合良好.双向数据绑定可能是AngularJS最酷最实用的特性,将MVC的原理展现地淋漓尽致. AngularJS的工作原理是:HTML模板将会被浏览器解析到DOM中, DOM结构成为AngularJS编译器的输入.AngularJS将会遍历DOM模

  • AngularJs 弹出模态框(model)

    推荐阅读:详解AngularJS 模态对话框 $modal是一个可以迅速创建模态窗口的服务,创建部分页,控制器,并关联他们. $modal仅有一个方法open(options) templateUrl:模态窗口的地址 template:用于显示html标签 scope:一个作用域为模态的内容使用(事实上,$modal会创建一个当前作用域的子作用域)默认为$rootScope controller:为$modal指定的控制器,初始化$scope,该控制器可用$modalInstance注入 res

  • 详解JavaScript的AngularJS框架中的作用域与数据绑定

    AngularJS 简介 AngularJS 是由 Google 发起的一款开源的前端 MVC 脚本框架,既适合做普通 WEB 应用也可以做 SPA(单页面应用,所有的用户操作都在一个页面中完成).与同为 MVC 框架的 Dojo 的定位不同,AngularJS 在功能上更加轻量,而相比于 jQuery,AngularJS 又帮您省去了许多机械的绑定工作.在一些对开发速度要求高,功能模块不需要太丰富的非企业级 WEB 应用上,AngularJS 是一个非常好的选择.AngularJS 最为复杂同

  • angularjs学习笔记之双向数据绑定

    这次我们来详细讲解angular的双向数据绑定. 一.简单的例子 这个例子我们在第一节已经展示过了,要看的移步这里 这里实现的效果就是,在输入框输入内容,下面也会相应的改变对应的内容.这就实现了数据双向绑定. 二.取值表达式与ng-bind的使用 我们再看一个例子,点击这里,文中出现的第一个例子中,{{greeting.text}}和{{text}}就是一个取值表达式了,但是如果你一直刷新页面,你会发现这样一个问题,那就是页面有时候会一瞬间的出现"{{greeting.text}} {{text

  • angularjs在ng-repeat中使用ng-model遇到的问题

    在ng-repeat中使用ng-model时会有许多问题,有的人碰到无法获取绑定的数据内容,有的人遇到改动绑定的数据内容时所有循环生成的内容一起改变.上面的问题我在开发时也遇到过,但是解决后我却怎么也还原不了那种情况了,只能先简单介绍一下无法获取的情景该如何解决. 例如: html: <body> <div ng-controller="selectController"> <div ng-repeat="pop in citylist"

随机推荐