深入浅析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 相关文章推荐
javascript 子窗体父窗体相互传值方法
May 31 Javascript
js函数获取html中className所在的内容并去除标签
Sep 08 Javascript
jquery导航制件jquery鼠标经过变色效果示例
Dec 05 Javascript
javascript引用赋值(地址传值)用法实例
Jan 13 Javascript
利用jQuery及AJAX技术定时更新GridView的某一列数据
Dec 04 Javascript
js表单处理中单选、多选、选择框值的获取及表单的序列化
Mar 08 Javascript
原生JS上传大文件显示进度条 php上传文件代码
Mar 27 Javascript
jQuery实现输入框的放大和缩小功能示例
Jul 21 jQuery
详解vue移动端项目代码拆分记录
Mar 15 Javascript
vue cli 3.x 项目部署到 github pages的方法
Apr 17 Javascript
JavaScript实现刮刮乐效果
Nov 01 Javascript
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
Jan 05 Vue.js
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操作MongoDB GridFS 存储文件的详解
2013/06/20 PHP
YII框架http缓存操作示例
2019/04/29 PHP
JavaScript高级程序设计 阅读笔记(十八) js跨平台的事件
2012/08/14 Javascript
仿谷歌主页js动画效果实现代码
2013/07/14 Javascript
js截取中英文字符串、标点符号无乱码示例解读
2014/04/17 Javascript
jQuery对val和atrr(&quot;value&quot;)赋值的区别介绍
2014/09/26 Javascript
express的中间件cookieParser详解
2014/12/04 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
JS 动态加载js文件和css文件 同步/异步的两种简单方式
2016/09/23 Javascript
C#微信小程序服务端获取用户解密信息实例代码
2017/03/10 Javascript
AngularJS使用ocLazyLoad实现js延迟加载
2017/07/05 Javascript
webpack打包react项目的实现方法
2018/06/21 Javascript
在Vue-cli里应用Vuex的state和mutations方法
2018/09/16 Javascript
详解ES7 Decorator 入门解析
2019/02/18 Javascript
微信小程序一周时间表功能实现
2019/10/17 Javascript
基于JS正则表达式实现模板数据动态渲染(实现思路详解)
2020/03/07 Javascript
在antd4.0中Form使用initialValue操作
2020/11/02 Javascript
恢复百度云盘本地误删的文件脚本(简单方法)
2017/10/21 Python
TF-IDF与余弦相似性的应用(一) 自动提取关键词
2017/12/21 Python
Python查看微信撤回消息代码
2018/06/07 Python
Python面向对象程序设计类的封装与继承用法示例
2019/04/12 Python
Python 安装第三方库 pip install 安装慢安装不上的解决办法
2019/06/18 Python
Django中的静态文件管理过程解析
2019/08/01 Python
TensorFlow加载模型时出错的解决方式
2020/02/06 Python
Python双链表原理与实现方法详解
2020/02/22 Python
python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析
2020/03/08 Python
安纳塔拉酒店度假村及水疗官方网站:Anantara Hotel
2016/08/25 全球购物
具有防紫外线功能的高性能钓鱼服装:Hook&Tackle
2018/08/16 全球购物
美国单身专业人士在线约会网站:EliteSingles
2019/03/19 全球购物
英国绿色商店:Natural Collection
2019/05/03 全球购物
主持人婚宴答谢词
2014/01/28 职场文书
材料专业毕业生求职信
2014/02/26 职场文书
公司委托书范本5篇
2014/09/20 职场文书
元旦主持词开场白
2015/05/29 职场文书
如何写一份成功的商业计划书
2019/06/25 职场文书