1.1 四大特性
MVC
<!doctype html>
<html ng-app>
<body>
<div ng-controller="HelloAngular">
<p>{{greeting.text}}, Angular</p>
</div>
<script src="js/angular-1.3.0.js"></script>
<script>
function HelloAngular($scope) {
$scope.greeting = {
text: 'Hello'
};
}
</script>
</body>
</html>
模块化与依赖注入
<!doctype html>
<html ng-app="app">
<body>
<div ng-controller="HelloAngular">
<p>{{greeting.text}}, Angular</p>
</div>
<script src="js/angular-1.3.0.js"></script>
<script>
var myModule = angular.module("app", []);
myModule.controller("HelloAngular", ['$scope',
function($scope) {
$scope.greeting = {
text: 'Hello'
};
}
]);
</script>
</body>
</html>
双向数据绑定
<!doctype html>
<html ng-app>
<body>
<input ng-model="greeting.text" />
<p>{{greeting.text}},AngularJS</p>
<script src="js/angular-1.3.0.js"></script>
</body>
</html>
指令
<!doctype html>
<html ng-app="app">
<body>
<hello></hello>
<script src="js/angular-1.3.0.js"></script>
<script>
var myModule = angular.module("app", []);
myModule.directive("hello", function () {
return {
restrict: 'E',
template: '<div>Hi everyone!</div>',
replace: true
}
});
</script>
</body>
</html>
1.2 开发环境
node.js | JS 运行环境 |
Bower | 插件管理(相当于 NuGet) |
Grunt | 代码混淆、合并工具 |
Sublime | 代码编辑器(小巧),Zen Coding 快速编写 HTML/CSS 代码 |
WebStorm | 代码编辑器(强大) |
git 小乌龟 | 版本管理 |
2.1 MVC
Controller 使用要点:
不要复用 Controller
不要操作 DOM
不要做数据格式化,ng 有表单控件
不要做数据过滤,ng 有 $filter
$scope 作用域
<!doctype html>
<html ng-app>
<head>
<style>
.show-scope-demo .ng-scope, .show-scope-demo .ng-scope { border: 1px solid red; margin: 3px; }
</style>
</head>
<body>
<div class="show-scope-demo">
<div ng-controller="GreetCtrl">
Hello {{name}}!
</div>
<div ng-controller="ListCtrl">
<ol>
<li ng-repeat="name in names">
{{name}} from {{department}}
</li>
</ol>
</div>
</div>
<script src="js/angular-1.3.0.js"></script>
<script>
function GreetCtrl($scope, $rootScope) {
$scope.name = 'World';
// 在根作用域定义了 department,在 ListCtrl 控制器中也能用
$rootScope.department = 'Angular';
}
function ListCtrl($scope) {
$scope.names = ['Igor', 'Misko', 'Vojta'];
}
</script>
</body>
</html>
<!doctype html>
<html ng-app>
<head>
<style>
.show-scope-demo .ng-scope, .show-scope-demo .ng-scope { border: 1px solid red; margin: 3px; }
</style>
</head>
<body>
<div ng-controller="EventController">
Root scope
<tt>MyEvent</tt> count: {{count}}
<ul>
<li ng-repeat="i in [1]" ng-controller="EventController">
<button ng-click="$emit('MyEvent')">
$emit('MyEvent')
</button>
<button ng-click="$broadcast('MyEvent')">
$broadcast('MyEvent')
</button>
<br>
Middle scope
<tt>MyEvent</tt> count: {{count}}
<ul>
<li ng-repeat="item in [1, 2]" ng-controller="EventController">
Leaf scope
<tt>MyEvent</tt> count: {{count}}
</li>
</ul>
</li>
</ul>
</div>
<script src="js/angular-1.3.0.js"></script>
<script>
function EventController($scope) {
$scope.count = 0;
$scope.$on('MyEvent', function () {
$scope.count++;
});
}
</script>
</body>
</html>
$emit:向上传播
$broadcast:向下传播
ng-repeat="i in [1, 2]":循环固定项
$scope 是一个树形结构,与 DOM 平行
子 $scope 对象会继承父 $scope 上的属性和方法
每个 Angular 应用只有一个根 $scope,一般位于 ng-app 上
$scope 可以传播事件,类似 DOM 事件,可向上可向下
2.2 路由、模块、依赖注入
var bookStoreApp = angular.module('bookStoreApp', [
'ngRoute', 'ngAnimate', 'bookStoreCtrls', 'bookStoreFilters',
'bookStoreServices', 'bookStoreDirectives'
]);
bookStoreApp.config(function($routeProvider) {
$routeProvider.when('/hello', {
templateUrl: 'tpls/hello.html',
controller: 'HelloCtrl'
}).when('/list',{
templateUrl:'tpls/bookList.html',
controller:'BookListCtrl'
}).otherwise({
redirectTo: '/hello'
})
});
2.3 双向数据绑定
绑定方式1:<p>{{greeting.text}}, Angular</p>
绑定方式2:<p><span ng-bind="greeting.text"></span>, Angular</p>
方式1 在加载 angular.js 之前会将 {{***}} 显示于界面,因此在 index.html 页面建议用方式2,通过模板加载的页面上的绑定可以使用方式1。
<!doctype html>
<html ng-app="UserInfoModule">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
</head>
<body>
<div class="panel panel-primary">
<div class="panel-heading">
<div class="panel-title">双向数据绑定</div>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" role="form" ng-controller="UserInfoCtrl">
<div class="form-group">
<label class="col-md-2 control-label">
邮箱:
</label>
<div class="col-md-10">
<input type="email" class="form-control" placeholder="推荐使用126邮箱" ng-model="userInfo.email">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">
密码:
</label>
<div class="col-md-10">
<input type="password" class="form-control" placeholder="只能是数字、字母、下划线" ng-model="userInfo.password">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="userInfo.autoLogin">自动登录
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-default" ng-click="getFormData()">获取Form表单的值</button>
<button class="btn btn-default" ng-click="setFormData()">设置Form表单的值</button>
<button class="btn btn-default" ng-click="resetForm()">重置表单</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="js/angular-1.3.0.js"></script>
<script>
var userInfoModule = angular.module('UserInfoModule', []);
userInfoModule.controller('UserInfoCtrl', ['$scope',
function ($scope) {
$scope.userInfo = {
email: "253445528@qq.com",
password: "253445528",
autoLogin: true
};
$scope.getFormData = function () {
console.log($scope.userInfo);
};
$scope.setFormData = function () {
$scope.userInfo = {
email: 'damoqiongqiu@126.com',
password: 'damoqiongqiu',
autoLogin: false
}
};
$scope.resetForm = function () {
$scope.userInfo = {
email: "253445528@qq.com",
password: "253445528",
autoLogin: true
};
}
}
]);
</script>
</body>
</html>
注意 ng-click 的用法。
ng-class 用法:
ng-class='{bg-danger: isError, bg-success: isSuccess}'
表示当 isError 为 true 时应用 bg-danger 样式,当 isSuccess 为 true 时应用 bg-success 样式。
ng-show / ng-hide 用法:
ng-show='isShow'
表示当 isShow 为 true 时显示,否则隐藏。
2.4 指令(Directive)重要!
路由
Angular 自带的 angular.route.js 不能实现嵌套路由,推荐使用 UI-Router,方便将页面分割成多个 ui-view 实现局部更新。
angular.module("app", []).directive("directiveName", function () {
return {
//通过设置项来定义
};
});
设置项:
restrict: 'AEMC', // A 属性(默认),E 元素,M 注释,C 样式
template: '<div>xxx</div>', // 替代的 HTML
replace: true, // 替代
transclude: true, // 嵌套,需要 template 配合,例如:
templace: '<div>xxx <div ng-transclude></div></div>', // 原来指令标签中的内容会被放置于 ng-transclude 所在 div 中。
templaceUrl: 'xxx.html', // 使用独立 html 的模板内容
compile: function() { }, // 对模板自身进行转换
link: function() {}, // 操作 DOM、绑定事件监听器
可以在页面中使用 ui-sref 或控制器中 $state.go 来实现跳转(页面更新)
如何传递参数:
一个简单的示例:在一个文章列表页面和一个文章详情页面中实现跳转,需要传递参数文章 id
在路由配置 state 中加入:params: { "id": null }
在列表行中绑定 id,格式如:<a ui-sref="app.blog.item({id:row.id})"><span>Edit</span></a>
在详情页控制器中接收参数:$stateParams,即可用 $stateParams.id 来获取文章 id 值
如果需要同时更改地址栏 url,并且能够使用该 url 直接打开该文章,那么修改 state 中的 url 为 /item?id,体现为 #/app/blog/item?id=9,也可以用冒号 /item:id,体现为 #/app/blog/item9
scope 的绑定策略:
@:把当前属性作为字符串传递。你还可以绑定来自外层 scope 的值,在属性值中插入 {{ }} 即可
=:与父 scope 中的属性进行双向绑定
&:传递一个来自父 scope 的函数,稍后调用
ERP 类型的系统必备 UI 组件:MiniUI、Ext JS
互联网/电商型系统必备 UI 组件:KISSY
其它常用组件:AngularUI
2.5 Service 与 Provider
使用 $http.get 获取 JSON 数据
<!doctype html>
<html ng-app="app">
<head>
<meta charset="UTF-8">
<script src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
<div ng-controller="LoadDataCtrl">
<ul>
<li ng-repeat="user in users">
{{user.name}}
</li>
</ul>
</div>
<script>
var app = angular.module("app", []);
app.controller('LoadDataCtrl', ['$scope', '$http', function ($scope, $http) {
$http({
method: 'GET',
url: 'data.json'
}).success(function (data, status, headers, config) {
console.log("success...");
console.log(data);
$scope.users = data;
}).error(function (data, status, headers, config) {
console.log("error...");
})
}]);
</script>
</body>
</html>
data.json:
[
{ "name": "a" },
{ "name": "b" },
{ "name": "c" }
]
自定义 Service
<!doctype html>
<html ng-app="app">
<head>
<meta charset="UTF-8">
<script src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
<div ng-controller="ServiceController">
<label>用户名:</label>
<input type="text" ng-model="username" placeholder="请输入用户名" />
<ul ng-show="username">
<li ng-repeat="user in users">
{{user.name}}
</li>
</ul>
</div>
<script>
var app = angular.module("app", []);
app.factory('userListService', ['$http', function ($http) {
var doRequest = function (username, path) {
return $http({ method: 'GET', url: 'data.json' });
};
return {
userList: function (username) {
return doRequest(username, 'userList');
}
}
}]);
app.controller('ServiceController', ['$scope', '$timeout', 'userListService', function ($scope, $timeout, userListService) {
var timeout;
$scope.$watch('username', function (newUserName) {
if (newUserName) {
if (timeout) {
$timeout.cancel(timeout);
}
timeout = $timeout(function () {
userListService.userList(newUserName)
.success(function (data, status) {
$scope.users = data;
});
}, 350);
}
});
}]);
</script>
</body>
</html>
知识点:
$timeout 延时,防抖动
userListService 服务调用 $http 服务获取数据,返回一个对象
自定义 Service 命名不要以“$”开头,可以像内置 Service 一样注入的,注入时必须放在内置 Service 之后
Service 是单例的
Service 只要声明,不需要实例化
Service 在整个应用的生命周期中存在,可以用来共享数据
$filter
currency / date / filter / json / limitTo / lowercase / number / orderBy / uppercase
data 例:
{{ 1304375948024 | data }}
{{ 1304375948024 | data:"MM/dd/yyyy @ h:mma" }}
{{ 1304375948024 | data:"yyyy-MM-dd hh:mm:ss" }}
效果:
May 3, 2011
05/03/2011 @ 6:39AM
2011-05-03 06:39:08
自定义 filter:
<!doctype html>
<html ng-app="app">
<head>
<meta charset="UTF-8">
<script src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
{{'xoyozo'|filter1}}
<script>
var app = angular.module("app", []);
app.filter('filter1', function () {
return function (item) {
return item + 'o(u_u)o';
}
});
</script>
</body>
</html>
其它常用 Service:内置共 24 个
$compile 编译服务
$filter 数据格式化工具,内置了 8 个
$interval
$timeout
$locale
$location
$log
$parse
$http 封装了 ajax
2.6 综合实例 BookStore
官网示例 | 国内示例 | ||
Metronic | 收费 | 最新 | |
Unify | 收费 | ||
Angulr | 收费 | Angular HTML | 本站 Angular v2.2.0 本站 HTML v2.2.0 |
AdminLTE | 免费开源 | 最新 | 本站 v2.4.2 |
Color Admin | 收费 | 最新 | |
更多 …… |
浏览示例前,将以下域名的重定向加入到 hosts 中可以加快页面的打开速度:
127.0.0.1 fonts.googleapis.com
127.0.0.1 ajax.googleapis.com
127.0.0.1 player.vimeo.com
127.0.0.1 www.vimeo.com
收录了一些个人觉得不错的网页开发插件。
由于插件更新频繁,本页如有错误请指正,也欢迎告知更多功能强大、使用方便的插件。
插件 | 简介 | 备注 |
框架 | ||
jQuery | 最流行的 JS 框架 | 下载、中文文档、英文整合文档、中文整合文档,浏览器支持、来自 css88 的文档 官方建议 IE 6-8 使用 1.12.4 |
Angular、中文版 AngularJS (version 1.x) | 一套框架,多种平台同时适用手机与桌面 | MVC 架构,使得开发现代的单一页面应用程序(SPAs:Single Page Applications)变得更加容易 |
Vue.js | 是一套用于构建用户界面的渐进式框架。 | |
Bootstrap、中文版 | 简洁、直观、强悍的前端开发框架 | 英文文档、v3中文文档、v2中文文档、视频教程,主题和模板 |
jQuery UI | 为 jQuery 提供更丰富的功能 | 示例:Datepicker、Color Animation、Shake Effect |
功能 | ||
jQuery File Upload | jQuery 文件上传 | 英文文档 |
jQuery Cookie | 读取、写入和删除 cookie | 浏览器支持,文档 |
json2.js | json 操作库 | 已弃用,旧 IE 用 jQuery 的 parseJSON,HTML 5 用 JSON.parse |
Lightbox | 老牌图片浏览插件 推荐使用更强大的 Viewer.js | |
Swiper、中文版 | 最现代的移动触摸滑块(Most Modern Mobile Touch Slider) | 英文文档,中文文档,旧浏览器支持版本:2.x.x,Swiper 2 英文文档,中文文档 |
jquery-cropper | 图片裁剪 | |
FastClick | 用于消除手机浏览器上触摸事件触发之间的 300 毫秒延迟 | 用法,不应用的场景 |
PACE | 页面加载进度条 | 文档,IE8+ |
toastr | jQuery 通知 | 文档 |
Autosize | 一款小巧的,可自动调整 textarea 高度的独立脚本 | IE9+ |
X-editable | 允许您在页面上创建可编辑元素 | 文档,Demo |
select2 | 一款提供搜索过滤、自定义样式的下拉框插件 | |
jQuery Tags Input | 标签输入框 | 用法 |
Viewer.js | 图片浏览插件 | GitHub(viewerjs)、GitHub(jquery-viewer) jquery-viewer 是 viewerjs 的 jQuery 插件,即在 jQuery 环境中要同时引用这两个脚本。 |
PDF.js | A general-purpose, web standards-based platform for parsing and rendering PDFs. | |
编辑器 | ||
UEditor | 百度在线编辑器 | GitHub 下载、文档、ASP.NET 部署教程 |
日期时间 | ||
bootstrap-datepicker | Bootstrap 日期选择器 | Online Demo |
DateTimePicker | 日期时间选择 | |
MultiDatesPicker | 多日期选择 | |
FullCalendar | 日历日程事件工作表 | IE 9+, jQuery 2.0.0+ |
TimeTo | 计时、倒计时 | |
图表 | ||
D3.js | D3.js 是基于数据驱动文档工作方式的一款 JavaScript 函数库,主要用于网页作图、生成互动图形,是最流行的可视化库之一。 | |
Highcharts、中文版 | 兼容 IE6+、完美支持移动端、图表类型丰富、方便快捷的 HTML5 交互性图表库 | 文档 |
ECharts | 百度图表控件 | |
AntV | 来自蚂蚁金服的专业、简单、无限可能的可视化解决方案 G2 - 专业易用的可视化类库 G2-mobile - 移动端高性能可视化类库 G6 - 关系图可视化类库 | 流程图, 关系图, 可视化规范, 地图, 河流图, 力导图, 网络图, UML图, 业务流程图, 时序图 |
SyntaxHighlighter | 功能齐全的代码语法高亮插件(JS) | |
动态排名数据可视化 | 将历史数据排名转化为动态柱状图图表 开源代码,非插件,修改使用 | GitHub、视频教程、EV录屏、网页示例、视频效果 |
图标 | ||
Font Awesome | 完美的图标字体 | IE 8+,v3.2.1 支持 IE 7,进阶用法(定宽/边框/动画/旋转/叠加) |
Glyphicons | 图标字体 | 作为 Bootstrap 组件 |
Iconfont | 阿里巴巴矢量图标库 | 用户可以自定义下载多种格式的 icon,也可将图标转换为字体,便于前端工程师自由调整与调用 |
UI 框架 | ||
WeUI | 同微信原生视觉体验一致的基础样式库 | Demo、Wiki |
Apple UI Design Resources | 苹果用户界面设计资源 |
Angulr(没有字母“a”)是一款收费的 Bootstrap Admin Template,我们选择使用 Angular 版本是因为他提供很好的单页应用程序(Single-page application, SPA)用户体验。
官方演示地址:http://flatfull.com/themes/angulr/angular/
主要目录结构:
┌ angular | |
│├ api | |
│├ css | |
││└ app.min.css | 应用主样式 |
│├ fonts | |
││└ sourcesanspro | 应用字体库 |
│├ img | |
│├ js | |
││├ app | |
│││└ */*.js | 功能模块控制器 |
││├ controllers | |
│││└ *.js | 组件控制器 |
││└ app.angular.js | 应用主脚本 |
│├ l10n | |
││└ *.js | 语言配置文件 |
│├ tpl | |
││├ blocks | |
│││ └ *.html | 主框架部件 |
││└ *.html | 功能模块页 |
│└ index.html | 入口文件 |
│ | |
└ libs | 库 |
├ angular | |
│└ */*.* | Angular 插件 |
├ assets | |
│└ */*.* | Angulr 插件 |
└ jquery | |
└ */*.* | jQuery 插件 |
app.angular.js 中配置了 app 名称(name)、版本(version)、语言(langs),以及框架文件(tpl/app.html)、默认首页(/app/dashboard)、路由表(state)和插件库引用等信息。
首页配置导航菜单项,在 nav.html 中所有菜单项被包含在 <ul class="nav" /> 中,class 含“hidden-folded padder”的是菜单分区名称(如 Navigation),除了第一个,都被 class 含“line dk”的 li 留白,class 含“nav-sub”的 ul 是二级菜单,<i /> 是 icon,<b /> 是 badge,“font-bold”是加粗,translate 是配置多语言的键值。
Angulr 使用 UI-Router 实现路由。ui-sref 是路由键值,只有在 app.angular.js 的路由表中已配置值,该 ui-sref 才会被解释为 href。
以 Timeline 页为例,ui-sref="app.ui.timeline",route 的 state 中指定读取模板文件为 tpl/ui_timeline.html,且访问 url 为 /timeline,而父路由 app 和 app.ui 的 url 分别为 /app 和 /ui,所以该页实际访问路径后缀为 #/app/ui/timeline。
父路由中一般指定 template: "<div ui-view></div>",如果需要载入动画效果,在该 div 中加入相应的 class 即可(fade-*)。ui-view 作为一个容器,用来承载子路由指向的内容,实现路由嵌套。
目前为止,点击菜单项可准确显示页面内容。但当我们复制地址栏中的网址在新窗口中打开时,如果要将菜单自动展开定位到对应相,只要在 <li /> 标签上加上 ui-sref-active="active" 即可,若该项是子菜单,同时需要展开一级菜单,那么在一级菜单的 <li /> 标签上加上 ng-class="{active:$state.includes('app.ui')}",意思是在路由键中包含 app.ui 即展开此菜单。
如果页面需要引入脚本或样式,在路由的 state 上加上 resolve 参数即可,如果是插件(比如 ngGrid),会调用 MODULE_CONFIG(在 app.angular.js)中配置的该插件的相关脚本和样式。