\ 简介
知识储备:在开始学习 Angular 之前,只需要具备以下基础知识:HTML CSS Javascript,相对来说,后端用到得更多,简称: ng, 一款非常优秀的前端高级JS框架,已被 Google 收购
中文网站:https://www.angular.cn/
查看 web 资源库最火框 https://www.awesomes.cn/weuse
相关链接:
http://www.cnblogs.com/powertoolsteam/p/angularjs-introdection.html
http://www.apjs.net/
http://www.angularjs.cn/
http://docs.angularjs.cn/api
https://material.angularjs.org
http://angular-ui.github.io/
带领当前市面上的框架走向模式化或者架构化
作用:
1.构建 SPA(单一页面应用程序) 应用程序 , 只有一个页面
请求的页面是一个空的,渲染页面后,客户端可能再发请求到服务器,请求需要的数据,好处:快, 局部刷新,减少请求大小 用到 # 的方式
music.163.com 网易音乐网站:播放音乐时,可搜索,在同一页面
2.通过指令扩展了 HTML(通过表达式绑定数据到 HTML)使得很少有 dom 操作了
特性: MVC 模块化 自动化双向数据绑定 指令系统
入门案例:
所有需要 ng 管理的代码必须被包裹在一个有 ng-app 指令的元素中
ng-app 是ng的入口,表示当前元素的所有指令都会被angular管理
(对每一个指令进行分析和操作)
<body>
<div ng-app>
<h1>使用NG实现双边数据绑定</h1>
<input type="text" placeholder="请输入你的姓名" ng-model="user.name">
<p>hello <strong>{{user.name}}</strong></p>
</div>
<script src="bower_components/angular/angular.js"></script>
</body>
ng-app 加 ng-init="'world'" 初始值
网页加载完毕,angular 自动开始执行,会开辟一块空间,用于存储页面上用到的数据模型
在HTML 中,ng-xxx 的属性称之为指令(Directive)有ng-app
表明此元素是 angular应用程序管理的边界
ng-model
指令把文本框的值绑定到变量 name 上
{{user.name}} 表达式把应用程序变量 name 绑定到某个 元素的 innerHTML
{{::user.name}} 单向的,只会建立模型到界面的同步
总结:
- angular 最大程序的减少了页面上的 DOM 操作,让 JS 更专注业务逻辑的代码
- 通过简单的指令结合业务逻辑与逻辑数据
- 通过自定义指令实现组件化编程
- 维护成本低
\ tips:运行官方文档
- 众所周知,angular 官网打不开,我们需要本地运行 angular 文档
- 下载最新的 angular 包,解压后有一个 docs 文件夹
- 必须通过 http 服务器访问该文档
- 可以通过 SublimeServer 或者 http-server 运行
在包目录下(不是 docs 目录),运行命令行:
hs -o
可自动将该目录加到 http 服务器上,并用浏览器打开网页
端口占用,改hs -o -p 8789
前提: npm 包中有 http-server , 可以帮我们启动一个静态服务器
\ installation
- 下载 angular 的包
https://github.com/angular/angular.js/releases - 使用 CDN 上的 angular.js ( CDN加速服务的静态资源公共库 )
优点: 快,减少总费用、带宽压力 - 使用 bower 安装
- 使用 npm 安装
\ MVC model view controller
- 是一种应用程序开发思想
- 主要目的是为了解决应用程序展示结构、业务逻辑的紧耦合关系
- 使应用程序的组成分成三部分,每个部分有明确职责,相互之间没有依赖
控制器–组织高度相应的模型
模型–就是用于存储数据
视图–用于展示数据
\ angular 基础
ng 中常见概念和基本用法
模块 Module
- angular 很重要的一个特性,实现模块编程
- 可以将重复使用的指令或过滤器之类做的模块,便于复用
- 控制器必须在某个模块下,其在执行函数时,会根据参数名字(
$scope
)自动注入对象
// 注册模块,通过 module 函数创建一个名字叫做 MyApp 的模块,在 HTML 中,ng-app='模块名'
// 第二个参数必写,可以为空,如果没有第二个参数,函数功能是找到已经定义的模块
var app = angular.module("myApp",[]);
// app.controller 方法用于创建一个名为'demoCtrl'控制器,所创建的控制器属于myApp模块
// 第一个参数 $scope 是固定的
app.controller("demoCtrl",function($scope){
// 控制器执行时自动执行的函数
// $scope 不仅仅可以往视图中暴露数据,还可以暴露行为
$scope.yh = {};
$scope.yh.name = "jjj";
$scope.show = function(){
console.log('show函数')
}
})
由于压缩代码会改变参数名称,注册控制器的标准方式就是通过传递数据的方式,最后一个是控制器函数,这里的参数名随意,前面的是字符串 ‘ http’
module.controller(‘demoCtrl’,[’$scope’], funct ion(a){…})
控制器的三种主要职责
- 为应用中的模型设置初始状态
- 通过 $scope 对象把数据模型或函数行为暴露
- 监视模型变化,做出相应动作
angular 基本不用操作 DOM,如果必要,可以使用 angular 提供的 jqlite
案例
输入用户名,密码,点击按钮,控制台输出用户信息
输入过程中,监视用户名输入,不同情况有不同提示
<body>
<div ng-app='myApp' ng-controller='singinCtrl' >
<input type="text" ng-model='user.name'><br/>
<input type="text" ng-model='user.pw'><br/>
<input type="button" value="点击" ng-click='showUs()'>
<p>{{message}}</p>
</div>
</body>
<script src="../pro_modules/angular-1.4.9/angular.js"></script>
<script>
var us = angular.module('myApp',[]);
us.controller('singinCtrl',['$scope',function($scope){
$scope.user = {
'name': '',
'pw': ''
}
$scope.message = 'yowx';
$scope.showUs = function(){
console.log($scope.user);
}
// 官方api中提供了一个 $scope.$watch 方法
// 第一个参数是要监控的数据,第二个参数是触发的函数,函数中2个参数是现在和之前的数据
$scope.$watch('user.name',function(now,old){
if(now){
if(now.length<8){
$scope.message = '字符太短';
} else {
$scope.message = "welcome";
}
} else {
$scope.message = "请输入用户名";
}
})
}])
</script>
$scope (上下文模型)
*视图和控制器之间的桥梁
*利用 $scope 暴露数据
插件 angularJS batarang (浏览器插件) 及时查看 $scope
使用时,控制台多一个 AngularJS 面板
谷歌: 地址栏输入 chrome-urls 回车 点击 extensions 找到插件 id到 chrome 网上应用店 下载 , 要翻墙
\ 表达式 {{ }}
字符串:{{ ‘hello’ + ‘world’ }}
数字: {{100 + 100 }}
对象:{{ us.name }}
数组: {{ arr[2] }}
字符串表达式:页面打印出 hello world
打开页面会内容会闪一下,解决:加 ng-app 时,再加 ng-cloak 但效果不明显
自己写 css: [ng-cloak],ng-cloak { display: none; }
ng-cloak 指令就是在 NG 指令执行完毕后自动移除
\ 指令
- angular 有一套完整的、可扩展的、用来帮助 web 应用开发的指令集
- 在建立 DOM 期间,和 HTML 关联着的指令会被检测到
- 在 angularJS 中将前缀为 ng-xxx 这种属性称为指令,其作用是为 DOM 元素调用方法、定义行为绑定数据等
- ng-xxx 的属性不是标准中定义的属性,很多情况下语法校验是不能通过的,html5 允许扩展的(自定义)属性,用 data-ng-app 也可以,二者效果一样
- angular 找到第一个 ng-app 过后,默认不会再找,要用 2 个 需要手动添加
angular.bootstrap
(document.querySelector(’[ng-app=“a2”]’), [‘myApp2’] );
还有一个解决:不要手动添加,而是将两个模块拼装
var myApp = angular.module(‘myApp’,[‘myApp1’, ‘myApp2’]);
html 上 2 个并列 div 的 ng-app 都删除,在其父元素上加 ng-app = ‘myApp’
常用内置指令
指令 | |
---|---|
ng-app | 用来标明一个 angularJS 程序,标记在其作用范围的根对象上,系统自动执行 可以在同一个页面创建多个 ng-app节点(不推荐) 标记的范围尽可以小,性能更好 |
ng-bind | 将作用域(scope) 的值绑定到元素的 innerHTML 上,效果比表达式好 如果绑定的内容有 HTML,会自动转义 |
ng-bind-html | 需要安装 bower install angular-sanitize --save 装完后要引包 … angular-sanitize.js还要依赖此模块 angular.module(‘myApp’,[‘ngSanitize’]) |
ng-repeat | 遍历数据中每一个元素 |
ng-class | 会根据当前设置对象的属性和属性值决定是否添加 class |
使用自定义的模块才可以依赖别的包定义的模块,angular 默认不依赖任何模块
<strong ng-bind='username'><strong>
username已用 ng-init 初始化,如果在strong标签中写表达式,打开页面数据会闪变一下,用 ng-bind 不会出现这种情况
绑定 html <h1>asdf</h1> 结果是字符串
ng-repeat 指令小案例:
<body ng-app='myApp'>
<ul ng-controller='ctrlArray'>
<li ng-repeat='item in data' > <span>{{$first ? "first" : '不是'}}</span>
<span>{{item.id}}</span>
<strong>{{item.mess}} </strong>
<span>{{item.age}}</span></li>
</ul>
<script src="../pro_modules/angular-1.4.9/angular.js"></script>
<script>
angular.module('myApp',[])
.controller('ctrlArray',['$scope',function($scope){
$scope.data = [];
for( var i=1; i< 10; i++){
$scope.data[$scope.data.length] = {
id: i,
mess: "消息" + i,
age: 23 + i
}
}
}])
</script>
</body>
控制台看 AngularJS 插件,查看$scope, 遍历的每一项都有特定属性,$id, $first 等,看是否第一个,最后一个
文字隔行换色,先设置样式 class: red, blue
给 li 加上class="{{$even ? 'red' : 'blue'}}"
也可用 ng-class='{red:$even,blue:$odd}'
ng-repeat案例: 数组中有重复的数据,直接以上用法 时会报错
要 ng-repeat="item in data track by $index
"
内容以李开头的颜色为红色 ng-class=“red:name.startWith
(‘李’)”
下拉框案例:不同值,div 背景不同,样式设置 red blue类,设置背景色
<select ng-model='bgc'>
<option value="red">red</option>
<option value="blue">blue</option>
</select>
<div id="box" ng-class='bgc'></div>
也可以 ng-class="{red: bgc=='red',blue:bgc=='blue'}"
loading 小案例: 页面打开 显示 loading 过一段时间消失
看代码: body 上有 loading 样式,再消失
<body ng-app='myApp' ng-controller="lddctrl">
<p>这是页面内容 </p>
<div id="box" ng-if="loading">
loading...
</div>
<script src="../pro_modules/angular-1.4.9/angular.js"></script>
<script>
angular.module('myApp',[])
.controller('lddctrl',['$scope','$timeout',function($scope,$timeout){
$scope.loading = true;
$timeout(function() {
$scope.loading = false;
}, 1000);
}]);
</script>
</body>
用到了
$timeout
ng-if="loading"
运行时有报错 Argument ‘lddctrl’ is not a function ,自己是因为自定义了模块 myApp , 但是在 body 上写时只写了 ng-app ,没有赋值 myApp,所以报错
用ng-class="{loading: loading}"
是怎么做的,没弄明白???
ng-cloak 指令
该指令用于在 angularJS 应用在加载时防止 angularJS 代码未加载完而出现的问题,可能出现闪烁的效果,用 ng-cloak 防止此问题发生
如 angular.js 在 head 中引入,不会出现上述问题,在 body最后引入需要 hack
<body ng-app ng-cloak>
<p>{{'hello world!!'}}</p> // 注意是字符串
ng-show \ ng-hide 指令
<div id="box" ng-show="false">
ng-hide="!loading" 出错,没弄明白
ng-src \ ng-href 指令
<body ng-app ng-init="imgUrl='../00pic/e.png'">
<img src="{{imgUrl}}" alt="">
上述页面会显示图片,但是会报错,用 ng-src 替换 img 中的 src 即可
ng-switch 指令
根据表达式显示或隐藏对应的部分
ng-switch-when 控制匹配是否情况
ng-switch-default 用于设置默认选项,如果没有其他项匹配,该项显示
<select ng-model="homeLand"> // 选择哪项,显示哪项
<option value="shanghai">上海</option>
<option value="beijing">北京</option>
<option value="shenzhen">深圳</option>
</select>
<div ng-switch="homeLand">
<div ng-switch-when="shanghai">
<p>上海,简称“沪”或“申”</p>
</div>
<div ng-switch-default>
<p>中国,是以华夏文明为源泉、中华</p>
</div>
</div>
全选案例:
<p><input type="checkbox" ng-model="fav">全选</p>
<ul>
<li><input type="checkbox" ng-checked='fav'>选项1</input></li>
<li><input type="checkbox" ng-checked='fav'>选项2</input></li>
<li><input type="checkbox" ng-checked='fav'>选项3</input></li>
</ul>
点击全选, ul 中的每个input会添加 checked属性
\ 自定义指令
案例:
html <it-btn></it-btn>
var myApp = angular.module('myApp',[]);
// 第一个参数是指令的名称,第二个参数是一个数组,数组的最后一个参数是函数
// 定义时要用驼峰法,使用时要用 -
myApp.directive('itBtn',[function(){
return {
template: '<div class="red">红色</div>'
}
}]);
案例:
html <btn prm='true'>transclude传值</btn>
var myApp = angular.module("myApp",[]);
myApp.directive('btn', [ function(){
// Runs during compile
return {
scope: {
prm:'@' // 传递的值
},
// restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
// template: '<button class="btn {{prm==\'true\' ? \'btn-primary\' : \'\'}}">button</button>',
template: '<button class="btn {{prm==\'true\' ? \'btn-primary\' : \'\'}} ng-transclude">button</button>',
// templateUrl: '',
replace: true, // 替换为指令中元素的值
// 指令对象的 transclude 必须设置为 true,才能在模板中使用 ng-transclude指令
transclude: true,
//link: function($scope, iElm, iAttrs, controller) {}
};
}]);
面包屑案例: 没弄明白
var myApp = angular.module('myApp',[]);
myApp.controller('bdcrumb',['$scope',function($scope){
$scope.pathData = {'a':'#','b':'#','c':'#','d':'#','e':'#'};
}])
myApp.directive('breadcrumb',[function(){
return {
scope:{},
restrict:'EA',
templateUrl: './86template.html',
link: function(scope,ele,attr){
scope.data = JSON.parse(attr.data);
}
}
}]);
<ol class="breadcrumb"> // li 类 active 最后一个
<li ng-class='{active:$last}' ng-repeat="(key, value) in data">
<a ng-if='!$last' href="#">{{key}}</a>
<span ng-if='$last' href="#">{{key}}</span> // 最后一个样式不同
</li>
</ol>
angular-ui
angular material
http://todomvc.com/ 用不用方式实现的todo