深入浅析AngularJS和DataModel


Posted in Javascript onFebruary 16, 2016

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;
})
}])
Javascript 相关文章推荐
JS 密码强度验证(兼容IE,火狐,谷歌)
Mar 15 Javascript
jQuery对html元素取值与赋值的方法
Nov 20 Javascript
利用jq让你的div居中的好方法分享
Nov 21 Javascript
jquery中获取元素里某一特定子元素的代码
Dec 02 Javascript
c#+jquery实现获取radio和checkbox的值
Sep 12 Javascript
JavaScript中的Math.LOG2E属性使用详解
Jun 14 Javascript
javascript实现倒计时跳转页面
Jan 17 Javascript
js实现table添加行tr、删除行tr、清空行tr的简单实例
Oct 15 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
Feb 22 Javascript
JavaScript之map reduce_动力节点Java学院整理
Jun 29 Javascript
vue+axios实现文件下载及vue中使用axios的实例
Sep 21 Javascript
Ajax实现三级联动效果
Oct 05 Javascript
Javascript中的Prototype到底是什么
Feb 16 #Javascript
剖析Node.js异步编程中的回调与代码设计模式
Feb 16 #Javascript
使用Node.js处理前端代码文件的编码问题
Feb 16 #Javascript
让图片跳跃起来  javascript图片轮播特效
Feb 16 #Javascript
Node.js本地文件操作之文件拷贝与目录遍历的方法
Feb 16 #Javascript
详解Node.js包的工程目录与NPM包管理器的使用
Feb 16 #Javascript
javascript每日必学之运算符
Feb 16 #Javascript
You might like
php读取html并截取字符串的简单代码
2009/11/30 PHP
PHP原理之异常机制深入分析
2010/08/08 PHP
PHP和Mysqlweb应用开发核心技术-第1部分 Php基础-2 php语言介绍
2011/07/03 PHP
PHP中time(),date(),mktime()区别介绍
2013/09/28 PHP
php json与xml序列化/反序列化
2013/10/28 PHP
在Win7 中为php扩展配置Xcache
2014/10/08 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
ThinkPHP框架实现的MySQL数据库备份功能示例
2018/05/24 PHP
在php的yii2框架中整合hbase库的方法
2018/09/20 PHP
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
js nextSibling属性和previousSibling属性概述及使用注意
2013/02/16 Javascript
JavaScript自定义事件介绍
2013/08/29 Javascript
javascript写的一个模拟阅读小说的程序
2014/04/04 Javascript
Javascript获取表单名称(name)的方法
2015/04/02 Javascript
js实现touch移动触屏滑动事件
2015/04/17 Javascript
jQuery中closest和parents的区别分析
2015/05/07 Javascript
JavaScript学习笔记之数组随机排序
2016/03/23 Javascript
vue.js项目nginx部署教程
2018/04/05 Javascript
[01:45]亚洲邀请赛互动指南虚拟物品介绍
2015/01/30 DOTA
python操作MySQL数据库具体方法
2013/10/28 Python
Python标准库urllib2的一些使用细节总结
2015/03/16 Python
Python及PyCharm下载与安装教程
2017/11/18 Python
Python实现去除图片中指定颜色的像素功能示例
2019/04/13 Python
详解python中index()、find()方法
2019/08/29 Python
Python多线程及其基本使用方法实例分析
2019/10/29 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
python定义类self用法实例解析
2020/01/22 Python
Python3爬虫RedisDump的安装步骤
2021/02/20 Python
英国在线房屋中介网站:Yopa
2018/01/09 全球购物
迟到检讨书400字
2014/01/13 职场文书
促销活动总结报告
2014/04/26 职场文书
党员志愿者活动方案
2014/08/28 职场文书
学生考试舞弊检讨书
2015/01/01 职场文书
幼儿园万圣节活动总结
2015/05/05 职场文书
导游词之金鞭溪风景区
2019/09/12 职场文书
导游词之青岛太清宫
2019/12/13 职场文书