深入浅析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 index()方法使用代码
Jun 02 Javascript
document.getElementById的简写方式(获取id对象的简略写法)
Sep 10 Javascript
当json键为数字时的取值方法解析
Nov 15 Javascript
AngularJS入门教程之学习环境搭建
Dec 06 Javascript
jQuery插件boxScroll实现图片轮播特效
Jul 14 Javascript
js实现适用于素材网站的黑色多级菜单导航条效果
Aug 24 Javascript
jQuery实现带渐显效果的人物多级关系图代码
Oct 16 Javascript
JS只能输入正整数的简单实例
Oct 07 Javascript
AngularJS定时器的使用与移除操作方法【interval与timeout】
Dec 14 Javascript
详解javascript 变量提升(Hoisting)
Mar 12 Javascript
有关vue 开发钉钉 H5 微应用 dd.ready() 不执行问题及快速解决方案
May 09 Javascript
解决vue elementUI 使用el-select 时 change事件的触发问题
Nov 17 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 json_encode奇怪问题说明
2011/09/27 PHP
php 文本文件的读取效率
2012/02/10 PHP
一个完整的PHP类包含的七种语法说明
2015/06/04 PHP
php支持断点续传、分块下载的类
2016/05/02 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
PHP合并数组的2种方法小结
2016/11/24 PHP
利用ajax和PHP实现简单的流程管理
2017/03/23 PHP
PHP设计模式之观察者模式定义与用法示例
2018/08/04 PHP
IE6与IE7中,innerHTML获取param的区别
2009/03/15 Javascript
JavaScript中的this实例分析
2011/04/28 Javascript
js中根据字数截取字符串,不能截断url
2012/01/12 Javascript
jQuery 在光标定位的地方插入文字的插件
2012/05/10 Javascript
div+css+js实现无缝滚动类似marquee无缝滚动兼容firefox
2013/08/29 Javascript
jquery、js调用iframe父窗口与子窗口元素的方法整理
2014/07/31 Javascript
jQuery插件开发的五种形态小结
2015/03/04 Javascript
TypeScript 学习笔记之基本类型
2015/06/19 Javascript
详解Bootstrap glyphicons字体图标
2016/01/04 Javascript
JS伪继承prototype实现方法示例
2018/06/20 Javascript
Angular6 用户自定义标签开发的实现方法
2019/01/08 Javascript
详解auto-vue-file:一个自动创建vue组件的包
2019/04/26 Javascript
基于mpvue的简单弹窗组件mptoast使用详解
2019/08/02 Javascript
Flutter实现仿微信底部菜单栏功能
2019/09/18 Javascript
vue+ts下对axios的封装实现
2020/02/18 Javascript
在Python中使用SimpleParse模块进行解析的教程
2015/04/11 Python
Python logging管理不同级别log打印和存储实例
2018/01/19 Python
Scrapy使用的基本流程与实例讲解
2018/10/21 Python
浅谈Python脚本开头及导包注释自动添加方法
2018/10/27 Python
Python如何将装饰器定义为类
2020/07/30 Python
详解Java中一维、二维数组在内存中的结构
2021/02/11 Python
Topman美国官网:英国著名的国际平价时尚男装品牌
2017/12/22 全球购物
技校生自我鉴定范文
2013/09/26 职场文书
学生个人的自我评价分享
2013/11/05 职场文书
个人求职信范文分享
2014/01/06 职场文书
党员干部观看《周恩来四个昼夜》思想汇报
2014/09/10 职场文书
学校班子个人对照检查材料思想汇报
2014/09/27 职场文书
Python中glob库实现文件名的匹配
2021/06/18 Python