深入浅析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 相关文章推荐
基于JQuery实现鼠标点击文本框显示隐藏提示文本
Feb 23 Javascript
jQuery学习笔记 操作jQuery对象 CSS处理
Sep 19 Javascript
javascript下使用Promise封装FileReader
Feb 19 Javascript
原生js仿淘宝网商品放大镜效果
Feb 28 Javascript
ES6学习笔记之Set和Map数据结构详解
Apr 07 Javascript
微信小程序 wx.request方法的异步封装实例详解
May 18 Javascript
vue中倒计时组件的实例代码
Jul 06 Javascript
解决Vue在封装了Axios后手动刷新页面拦截器无效的问题
Nov 08 Javascript
vue数据初始化initState的实例详解
Apr 11 Javascript
Vue Cli 3项目使用融云IM实现聊天功能的方法
Apr 19 Javascript
angular 服务随记小结
May 06 Javascript
js实现日历
Nov 07 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 select,radio和checkbox默认选择的实现方法
2010/05/15 PHP
php 冒泡排序 交换排序法
2011/05/10 PHP
PHP中使用FFMPEG获取视频缩略图和视频总时长实例
2014/05/04 PHP
PHP人民币金额转大写实例代码
2015/10/02 PHP
php上传excel表格并获取数据
2017/04/27 PHP
thinkPHP5框架设置404、403等http状态页面的方法
2018/06/05 PHP
HTML中事件触发列表与解说
2007/07/09 Javascript
javascript让setInteval里的函数参数中的this指向特定的对象
2010/01/31 Javascript
用js实现的自定义的对话框的实现代码
2010/03/21 Javascript
js读写json文件实例代码
2014/10/21 Javascript
javascript基本包装类型介绍
2015/04/10 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
AngularJS中处理多个promise的方式
2016/02/02 Javascript
基于jQuery的Web上传插件Uploadify使用示例
2016/05/19 Javascript
NodeJS学习笔记之Module的简介
2017/03/24 NodeJs
Vue.js实战之组件的进阶
2017/04/04 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
使用validate.js实现表单数据提交前的验证方法
2018/09/04 Javascript
在vue中获取token,并将token写进header的方法
2018/09/26 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
一文快速详解前端框架 Vue 最强大的功能
2019/05/21 Javascript
JS中FormData类实现文件上传
2020/03/27 Javascript
解决VUE-Router 同一页面第二次进入不刷新的问题
2020/07/22 Javascript
python刷投票的脚本实现代码
2014/11/08 Python
Python数据类型详解(三)元祖:tuple
2016/05/08 Python
带你了解python装饰器
2017/06/15 Python
Python实现输出程序执行进度百分比的方法
2017/09/16 Python
对python中Json与object转化的方法详解
2018/12/31 Python
Tensorflow 卷积的梯度反向传播过程
2020/02/10 Python
Python3.9最新版下载与安装图文教程详解(Windows系统为例)
2020/11/28 Python
大连导游词
2015/02/12 职场文书
向雷锋同志学习倡议书
2015/04/27 职场文书
小学体育课教学反思
2016/02/16 职场文书
导游词创作书写原则以及开场白技巧怎么学?
2019/09/25 职场文书
MySQL 使用自定义变量进行查询优化
2021/05/14 MySQL
Nginx 502 bad gateway错误解决的九种方案及原因
2022/08/14 Servers