《AngularJs实战》学习笔记(慕课网)
1. Controller使用过程中的注意点
- 不要试图去复用Controller, 一个控制器一般只负责一小块视图
- 不要在Controller中操作DOM, 这不是控制器的职责. 封装在指令里.
- 不要在Controller中做数据格式化, ng有很好用的表单控件
- 不要在Controller里面做数据过滤操作, ng有$filter服务
- 一般来说, Controller是不会互相调用的, 控制器之间的交互会通过事件进行 ---> 这是强耦合
2.
<html ng-app> <!--这里ng-app告诉浏览器,这里的html元素是AngularJS应用程序的“所有者”-->
<div>
<input ng-model="greeting.text"/> <!--ng-model把输入域的值绑定到应用程序变量greeting.text-->
<p>{{greeting.text}}, Angular</p> <!-- 双大括号{{}}是AngularJS表达式:把数据绑定到HTML,与ng-bind指令异曲同工。-->
<!-- AngularJS将在表达式书写的位置“输出”数据--> <!--它很像JS表达式,可以包含文字,运算符和变量-->
</div>
....
<script src="js/angular-1.3.0.js"></script>
<html>
则p标签中的值会随着input里的输入进行改变.
启动后, 会找ng-app中的指令. 找到ng-model后会生成greeting.text数据模型, 这个模型挂载scope根目录下, 这样所有的{{greeting.text}}都可以获得其值
3. AngularJS四大核心特性
- MVC
- 模块化和依赖注入
- 双向数据绑定
- 指令
4. 关于$scope
- Angularjs的MVC是借助于$scope实现的:
- 作用域也是有层次结构的, 如果在内层作用域中没有找到值则会向上去找, 类似JS中的原型查找
- $scope是一个POJO(Plain Old JavaScript Object)
- $scope提供了一些工具方法$watch()/$apply()
- $scope是表达式的执行环境(或者叫作用域)
- $scope是一个树形结构, 与DOM标签平行
- 子$scope对象会继承父$scope上的属性和方法
- 每一个Angular应用只有一个根$scope对象(一般位于ng-app上)
- $scope可以传播事件, 类似DOM事件, 可以向下也可以向上
- $scope不仅是MVC的基础, 也是后面实现双向数据绑定的基础
- 可以用angular.element($0).scope()进行调试
- $scope的生命周期: Creation->Watcher registration->Model mutation->Mutation observation->Scope destruction
5. AngularJS模块化
var helloModule=angular.module('HelloAngular',[]);
helloModule.controller('helloNgCtrl', ['$scope', function($scope){
$scope.greeting = {
text: 'Hello'
};
}]);
一个完整项目结构
[目录]BookStore
| [目录]app
| | [目录]css
| | [目录]framework
| | [目录]imgs
| | [目录]js.............................存放js文件
| | | app.js.........................作为启动点的js
| | | controllers.js
| | | directives.js
| | | filters.js
| | |- services.js
| | [目录]tpls...........................放一些模板,即不完整的html文件片段
| | | bookList.html
| | |- hello.html
| |- index.html..........................应用的html文件
| [目录]node_modules.......................各种基于NodeJS的工具
| | [目录]http-server
|- |- package.json........................npm配置项
- ng-app:定义应用程序的根元素
- ng-bind:绑定HTML元素到应用程序数据
- ng-bind-html:绑定HTML元素的innerHTML到应用程序数据,并移除HTML字符串中危险字符
- ng-bind-template:规定使用膜拜替换的文本内容
- ng-blur:规定blur事件的行为
- ng-change:规定在内容改变时要执行的表达式
- ng-checked:规定元素是否被选中
- ......更多参见 AngularJS指令
- AngularJS模块(Module)定义了AngularJS应用
- AngularJS控制器用于控制AngularJS应用
- ng-app指令定义了应用,ng-controller定义了控制器
6. 使用ngRoute进行视图之间的路由
$routeProvider.when('/hello',{ //$routeProvider提供路由, 当访问"hello"时会调用hello.html模板, 控制器HelloCtrl控制视图
templateUrl: 'tpls/hello.html',
controller:'HelloCtrl'
}).when('/list',{
templateUrl:'tpls/bookList.html',
controller:'BookListCtrl'
}).otherwise({
redirectTo: '/hello'
})
7. ng官方推荐的模块切分方式:
app
|
-----------------------------------------------
| | | | |
controllers directives services routes filters
- 任何一个ng应用都是由控制器, 指令, 路由, 过滤器等有限的模块类型构成的
- 控制器, 指令, 服务, 路由, 过滤器分别放在一个模块里面(可借助于grunt合并)
- 用一个总的app模块作为入口点, 它依赖其他所有模块
<!DOCTYPE html>
<html ng-app="bookStore">
<!-- ng-app只有一个,相当于main方法 -->
<head>
<title></title>
<script>.....</script>
</head>
<body>
<div ng-view> </div>
</body>
</html>//controller.js
1 var bookStoreApp = angular.module('bookStoreApp',[
'ngRoute','ngAnimate','bookStoreCtrls','bookStoreFilters',
'bookStoreServices','bookStoreDirectives'
]); //依赖注入. 模块之间的依赖的实现. 也可以加载angularjs自带的模块,比如ngAnimate, 记得在html中把script文件引入 bookStoreApp.config(function($routeProvider){
$routeProvider.when('/hello',{
templateUrl: 'tpls/hello.html',
controller:'HelloCtrl'
}).when('/list',{
templateUrl:'tpls/bookList.html',
controller:'BookListCtrl'
}).otherwise({
redirectTo: '/hello'
})
});//directives.js
var bookStoreDirectives = angular.module('bookStoreDirectives', []); bookStoreDirectives.directive('bookStoreDirective_1', ['$scope',
function($scope){}
]); bookStoreDirectives.directive('bookStoreDirective_2', ['$scope',
function($scope){}
]);//services.js
var bookStoreServices = angular.module('bookStoreServices', []); bookStoreServices.service('bookStoreService_1', ['$scope',
function($scope){}
]); bookStoreServices.service('bookStoreService_2', ['$scope',
function($scope){}
]);
8. ng-bind
如第2条所示的例子, 使用{{}}绑定数据时,可能会在页面加载过程中出现{{greeting.text}},使得页面不美观。 一个解决办法就是使用ng-bind
<!DOCTYPE html>
<html ng-app>
<head>
<title></title>
</head>
<body>
<div ng-controller="HelloAngular">
<p><span ng-bind="greeting.text"></span>,Angular</p>
</div>
</body>
<script src="js/angular-1.3.0.js"></script>
<script src="HelloAngular_MVC.js"></script>
</html>
所以,一般在首页加载时使用ng-bind。后面的页面可以使用{{}}来绑定
9. 双向绑定场景
- form表单
<!DOCTYPE html>
<html ng-app="userInfoModule">
<!-- ng-app指令定义了一个AngularJS应用程序 --> <head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
<script src="js/angular.js"></script>
<script src="Form.js"></script>
<title></title>
</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 class="form-control" type="email" placeholder="推荐使用126邮箱" ng-model="userInfo.email"></input>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">
密码:
</label>
<div class="col-md-10">
<input class="form-control" type="password" placeholder="只能是数字、字母、下划线" ng-model="userInfo.password"></input>
</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()">获取表单的值</button>
<button class="btn btn-default" ng-click="setFormData()">设置表单的值</button>
<button class="btn btn-default" ng-click="resetFormData()">重置表单</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>//这里等号右侧括号里第一个参数,模块的名称就是html中主函数入口“ng-app”的名称,即AngularJS应用的根元素
//AngularJS模块定义应用
var userInfoModule=angular.module('userInfoModule',[]); //AngularJS控制器控制应用
userInfoModule.controller('UserInfoCtrl',['$scope', function($scope){
$scope.userInfo={
email:"25344528@qq.com",
password:"12312313",
autoLogin:true
};
$scope.getFormData=function(){
console.log($scope.userInfo)
};
$scope.setFormData=function(){
$scope.userInfo={
email:'damoqiasss@124.sc',
password:"ssss",
autoLogin:false
}
};
$scope.resetFormData = function(){
$scope.userInfo={
email: "123456@a.cc",
password:"56",
autoLogin:true
}
}
}]) - 例子2:修改样式: 不需要直接操作标签,而是给类绑定不同的值从而使得p标签取得不同的样式属性
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!DOCTYPE html>
<html ng-app="myCSSModule">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="color.css">
<title></title>
</head> <body>
<div ng-controller="CSSCtrl">
<p class="text-{{color}}">测试CSS样式</p>
<button class="btn btn-default" ng-click="setGreen()">绿色</button>
<button class="btn btn-default" ng-click="setRed()">红色</button>
</div>
</body>
</html>
</body>
<script src="js/angular.js"></script>
<script src="color.js"></script>
</html>var module = angular.module("myCSSModule",[]); module.controller('CSSCtrl',['$scope', function($scope){
$scope.setGreen = function(){
$scope.color="green"
};
$scope.setRed = function(){
$scope.color="red"
}
}]).text-red{
color:red;
}
.text-green{
color:green;
}这里为了避免取不到color值得到text-null这样奇怪的东西,可以使用ng-class:
<!DOCTYPE html>
<html ng-app="MyCSSModule">
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.error{
background-color: red;
}
.warning{
background-color: yellow;
}
</style>
</head>
<body>
<div ng-controller="HeadController">
<div ng-class='{error: isError, warning: isWarning}'>{{messageText}}</div>
<!-- 如果isError是true就使用isError的样式,如果isWarning是true就使用warning的样式。error和warning定义在css中 -->
<button ng-click="showError()">Simulate Error</button>
<button ng-click="showWarning()">Simulate Warning</button>
</div>
</body>
<script type="text/javascript" src="js/angular.js"></script>
<script type="text/javascript">
var module = angular.module("MyCSSModule",[]); module.controller("HeadController",["$scope",function($scope){
$scope.isError = false;
$scope.isWarning = false;
$scope.showError = function(){
$scope.isError = true;
$scope.isWarning = false;
$scope.messageText = "Error!";
};
$scope.showWarning = function(){
$scope.isError = false;
$scope.isWarning = true;
$scope.messageText = "Warning!";
};
}])
</script>
</html>
- 控制标签的显示与隐藏ng-show. 以及ng-hide与之相反
<!DOCTYPE html>
<html ng-app="MyCSSModule">
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.error{
background-color: red;
}
.warning{
background-color: yellow;
}
</style>
</head>
<body>
<div ng-controller="HeadController">
<button ng-click="toggleMenu()">Toggle Menu</button>
<ul ng-show="menuState.show">
<!-- 使用menuState.show这个模型的值控制下面的li是否显示 -->
<li ng-click='stun()'>Stun</li>
<li ng-click='disintegrate()'>Disintegrate</li>
<li ng-click='erase()'>Erase from history</li>
</ul>
</div>
</body>
<script type="text/javascript" src="js/angular.js"></script>
<script type="text/javascript">
var module = angular.module("MyCSSModule",[]); module.controller("HeadController",["$scope",function($scope){
$scope.menuState={show:false};
$scope.toggleMenu = function(){
$scope.menuState.show = !$scope.menuState.show;
};
}])
</script>
</html> - 以及ngAnimate实现页面切换动画等
10. 前端路由
- 使用前端路由的原因:
- AJax请求不会留下History记录
- 用户无法直接通过URL进入应用中的指定页面(保存书签、链接分享给朋友)
- Ajax对SEO是个灾难
- 路由的例子:
// 要导入angular-route.js
1 var bookStoreApp = angular.module('bookStoreApp',[
2 'ngRoute','ngAnimate','bookStoreCtrls','bookStoreFilters',
3 'bookStoreServices','bookStoreDirectives'
4 ]); //依赖注入. 模块之间的依赖的实现. 也可以加载angularjs自带的模块,比如ngAnimate, 记得在html中把script文件引入
5
6 bookStoreApp.config(function($routeProvider){
7 $routeProvider.when('/hello',{
8 templateUrl: 'tpls/hello.html',
9 controller:'HelloCtrl'
10 }).when('/list',{
11 templateUrl:'tpls/bookList.html',
12 controller:'BookListCtrl'
13 }).otherwise({
14 redirectTo: '/hello'
15 })
16 });这个AngularJS提供的路由机制不能实现路由的深层次嵌套。 可以从github上下载angular-ui-router
<!-- tpl3/index.html -->
<div class="container">
<div ui-view="topbar"></div>
<div ui-view="main"></div>
</div>var routerApp = angular.module('routerApp',['ui.router']);
routerApp.config(function($stateProvider,$urlRouterProvider){
$urlRouterProvider.otherwise('/index');
$stateProvider
.state('index',{
url: '/index',
views: {
'': {
templateUrl:'tpls3/index.html'
},
'topbar@index' : {
templateUrl: 'tpl3/topbar.html'
},
'main@index': {
templateUrl: 'tpl3/home.html'
}
}
})
.state('index.usermng'),{
url: '/usermng',
views: {
'main@index': {
templateUrl: 'tpls3/usermng.html',
controller: function($scope, $state){
$scope.addUserType = function(){
$state.go("index.usermng.addusertype");
}
}
}
}
}
}) - 前端路由的基本原理
- 哈希#
- HTML5中新的history API
- 路由的核心是给应用定义“状态”
- 使用路由机制会影响到应用的整体编码方式(需要预先定义好状态)
- 考虑兼容性问题与“优雅降级”
11. 指令
- 自定义指令hello:
// HelloAngular_Directive.js
var myModule = angular.module("MyModule",[]);
myModule.directive("hello", function(){
return {
restrict: 'AEMC', //四个字母分别表示:属性,元素,注释,类
template: '<div>Hi everyone!</div>',
replace: true
}
});使用hello指令的4种方法:
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
</head> <body>
<!-- 法1:使用元素 -->
<hello></hello> <!-- 法2:使用 -->
<div hello></div> <!-- 法3:使用样式类 -->
<div class="hello"></div> <!-- 法4 -->
<!-- directive:hello -->
<div></div>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript" src="HelloAngular_Directive.js"></script>
</html> - restrict---匹配模式
- 默认使用“A” 属性的方式: <div my-menu=Products></div>
还有E-元素: <my-menu title=Products></my-menu>
C-样式类: <div class=my-menu:Products></div>
M-注释: <!-- directive: my-menu Products --> - 推荐使用元素和属性的方式使用指令
- 当需要创建带有自己的模板的指令时,使用元素名称的方式创建指令
- 当需要为已有的HTML标签增加功能时,使用属性的方式创建指令
- 默认使用“A” 属性的方式: <div my-menu=Products></div>
- template--模板
- template
- templateURl
- templateCache
....myModule.directive("hello".......
.....
template: $templateCache.get("hello.html"),
....
- replace: 元素内部写的内容是否会被替换
- transclude
template: "<div>Hello everyone!<div ng-transclude></div></div>
//元素内部的内容替换到ng-transclude里面去 - 指令执行的三个阶段 & compile和link:
- 加载阶段:
- 加载angular.js,找到ng-app指令,确定应用的边界
- 编译阶段
- 遍历DOM,找到所有指令;
- 根据指令代码中的template、replace、transclue转换DOM结构
- 如果存在compile函数则调用
- 链接阶段
- 对每一条指令运行link函数
- link函数一般用来操作DOM,绑定事件监听器
- 关于compile和link:
- compile函数用来对模板自身进行转换, 而link函数负责在模型和视图之间进行动态关联;
- 作用域在链接阶段才会被绑定到编译之后的link函数上
- compile函数仅仅在编译阶段运行一次,而对于指令的每个实例,link函数都会执行一次
- compile可以返回preLink和postLink函数,而link函数只会返回postLink函数
- 如果需要修改DOM结构,应该在postLink中来做这件事情,而如果在preLink中做这件事情会导致错误
- 大多数时候我们只要编写link函数即可
- 加载阶段:
- 使用directive和Controller绑定DOM事件
<!-- Directive&Controller.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div ng-controller="MyCtrl">
<loader>滑动加载</loader>
</div>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript" src="Directive&Controller.js"></script>
</html>//Directive&Controller.js
var myModule = angular.module("MyModule",[]); myModule.controller('MyCtrl',['$scope', function($scope){
$scope.loadData = function(){
console.log("加载数据中....");
}
}]); myModule.directive("loader", function(){
return {
restrict: 'AE',
link:function(scope,element,attr){
element.bind("mouseenter",function(){
scope.loadData();
//或者用下面的方法
scope.$apply('loadData()');
})
}
};
});如果要在不同的控制器中使用指令调用不同的函数,则可以在自定义的元素中定义不同的属性来规定调用的方法,比如:
<!-- Directive&Controller.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div ng-controller="MyCtrl1">
<loader howToLoad="loadData1()">滑动加载</loader>
</div>
<div ng-controller="MyCtrl2">
<loader howToLoad="loadData2()">滑动加载</loader>
</div>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript" src="Directive&Controller.js"></script>
</html>//Directive&Controller.js
var myModule = angular.module("MyModule",[]); myModule.controller('MyCtrl1',['$scope', function($scope){
$scope.loadData1 = function(){
console.log("加载数据中....111");
}
}]); myModule.controller('MyCtrl2',['$scope', function($scope){
$scope.loadData2 = function(){
console.log("加载数据中....222");
}
}]); myModule.directive("loader", function(){
return {
restrict: 'AE',
link:function(scope,element,attr){
element.bind("mouseenter",function(){
scope.$apply(attr.howtoload); //注意在定义属性中用的的howToLoad的驼峰命名法,在js里只要用小写就可
})
}
};
}); - Directive&Directive
<!-- Directive&Directive.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
</head>
<body>
<div class="row">
<div class="col-md-3">
<superman strength>动感超人----力量</superman>
</div>
</div>
<div class="row">
<div class="col-md-3">
<superman strength speed>动感超人2----力量+敏捷</superman>
</div>
</div>
<div class="row">
<div class="col-md-3">
<superman strength speed light>动感超人3----力量+敏捷+发光</superman>
</div>
</div>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript" src="Directive&Directive.js"></script>
</html>//Directive&Directive.js
var myModule = angular.module("MyModule",[]);
myModule.directive("superman", function(){
return {
scope: {},
restrict: 'AE',
//指令内部的controller,目的是给指令暴露出public方法给指令外部调用的
controller: function($scope){
$scope.abilities = [];
this.addStrength = function(){
$scope.abilities.push("strength");
};
this.addSpeed = function(){
$scope.abilities.push("speed");
};
this.addLight = function(){
$scope.abilities.push("light");
};
},
//如果想定义暴露出的public方法给指令外部调用就使用controller
//而link是用于处理指令内部的一些事物,比如给元素绑定事件,改变属性等
link: function(scope,element,attrs){
element.addClass('btn btn-primary');
element.bind('mouseenter',function(){
console.log(scope.abilities);
});
}
}
});
myModule.directive("strength", function(){
return {
//require意思是strength指令是依赖superman指令的。link就可以写第四个参数,则link中就可以直接调用supermanCtrl中暴露出来的方法了
require: '^superman',
link: function(scope, element, attrs, supermanCtrl){
supermanCtrl.addStrength();
}
}
}); myModule.directive("speed", function(){
return {
require: '^superman',
link: function(scope, element, attrs, supermanCtrl){
supermanCtrl.addSpeed();
}
}
}); myModule.directive("light", function(){
return {
require: '^superman',
link: function(scope, element, attrs, supermanCtrl){
supermanCtrl.addLight();
}
}
}); - 独立scope
<!-- IsolateScope.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
</head>
<body>
<hello></hello>
<hello></hello>
<hello></hello>
<hello></hello>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript" src="IsolateScope.js"></script>
</html>//IsolateScope.js
var myModule = angular.module("MyModule",[]);
myModule.directive("hello", function(){
return {
restrict: 'AE',
scope: {}, //如果不加这个配置项,一个改变其他都会改变
template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>',
replace: true
}
});scope的绑定策略
- @: 把当前属性作为字符串传递。 你还可以绑定来自外层scope的值,在属性值中插入{{}}即可
<!-- ScopeAt.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
</head>
<body>
<div ng-controller="MyCtrl">
<drink flavor="{{ctrlFlavor}}"></drink>
</div>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript">
var myModule = angular.module("MyModule",[]);
myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.ctrlFlavor = "百威";
}])
// myModule.directive("drink", function(){
// return {
// restrict: 'AE',
// template:"<div>{{flavor}}</div>",
// link: function(scope, element, attrs){
// scope.flavor = attrs.flavor;
// }
// }
// })
//以上可以直接写作:
myModule.directive("drink", function(){
return {
restrict:'AE',
scope: {
flavor: '@'
},
template: "<div>{{flavor}}</div>"
}
})
</script>
</html> - =: 与父scope中的属性进行双向绑定
<!-- ScopeEqual.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
</head>
<body>
<div ng-controller="MyCtrl">
Ctrl:
<br>
<input type="text" ng-model="ctrlFlavor">
<br>
Directive:
<br>
<drink flavor="ctrlFlavor"></drink>
</div>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript">
var myModule = angular.module("MyModule",[]);
myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.ctrlFlavor = "百威";
}])
myModule.directive("drink", function(){
return {
restrict:'AE',
scope: {
flavor: '='
},
template: '<input type="text" ng-model="flavor"/>'
}
})
</script>
</html> - &: 传递一个来自父scope的函数,稍后调用
<!-- ScopeAnd.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
</head>
<body>
<div ng-controller="MyCtrl">
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
</div>
</body>
<script type="text/javascript" src="../test01/js/angular.js"></script>
<script type="text/javascript">
var myModule = angular.module("MyModule",[]);
myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.sayHello = function(name){
alert("Hello "+name);
}
}])
myModule.directive("greeting", function(){
return {
restrict:'AE',
scope: {
greet: '&'
},
template: '<input type="text" ng-model="userName"/><br/>' +
'<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br>'
}
})
</script>
</html>
- @: 把当前属性作为字符串传递。 你还可以绑定来自外层scope的值,在属性值中插入{{}}即可
- form指令
- HTML原生的form表单是不能嵌套的,而Angular封装之后的form可以嵌套
- Angular为form扩展了自动校验、防止重复提交等功能;
- Angular对input元素的type进行了校验,一共提供了以下10种类型:
text, number, url, email, radio, checkbox, hidden, button, submit, reset
- Angular为表单内置了4种CSS样式:
ng-valid, ng-invaid, ng-pristine, ng-dirty
内置校验器:
require, minlength, maxlength
<!-- FormBasic.html -->
<!DOCTYPE html>
<html ng-app="TestFormModule">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="../test01/js/angular.js"></script>
</head>
<body>
<form name="myForm" ng-submit="save()" ng-controller="TestFormModule">
<input type="text" name="userName" ng-model="user.userName" required/>
<input type="password" name="password" ng-model="user.password" required/>
<input type="submit" ng-disabled="myForm.$invalid" />
</form>
</body>
<script type="text/javascript">
var myModule = angular.module("TestFormModule",[]);
myModule.controller("TestFormModule", function($scope){
$scope.user={
userName:'xxxxx',
password:''
};
$scope.save=function(){
alert("save!");
}
})
</script>
</html>
- 自定义指令
<!-- Expander.html -->
<!DOCTYPE html>
<html ng-app="expanderModule">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="../test01/js/angular.js"></script>
</head>
<body>
<div ng-controller="SomeController">
<expander class="expander" expander-title='title'>
{{text}}
</expander>
</div>
</body>
<script type="text/javascript">
var myModule = angular.module("expanderModule",[]);
myModule.directive("expander", function(){
return {
restrict: 'EA',
replace: true,
transclude: true,
scope: {
title : '=expanderTitle'
},
template: '<div>'
+ '<div class="title" ng-click="toggle()">{{title}}</div>'
+ '<div class="body" ng-show="showMe" ng-transclude></div>'
+ '</div>',
link: function(scope, element, attrs){
scope.showMe = false;
scope.toggle = function(){
scope.showMe = !scope.showMe;
}
}
}
});
myModule.controller('SomeController', function($scope){
$scope.title = '点击展开';
$scope.text = '这里是内部的内容';
});
</script>
</html> - 第三方指令库:angular-ui
12. Service和Provider:
- 使用$http服务
<!-- HTTPbasic.html -->
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="../test01/js/angular.js"></script>
</head>
<body>
<div ng-controller="LoadDataCtrl">
<ul>
<li ng-repeat="user in users">
{{user.name}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
var myModule = angular.module("MyModule",[]); myModule.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...");
});
//这里会报错:$http(...).success is not a function。好像现在得用$http().then()function了?
}]);
</script>
</html> - 创建自己的Service
- Service的特性
- Service都是单例的
- Service由$injector负责实例化
- Service在整个应用的生命周期中存在,可以用来共享数据
- 在需要使用的地方利用依赖注入机制注入Service
- 自定义的Service需要写在内置的Service后面
- 内置Service的命名以$符号开头,自定义Service应该避免
- Service,Factory,Provider本质上都是Provider
function provider(name, provider_){
if(isFunction(provider_)){
provider_ = providerInjector.instantiate(provider_);
}
if(!provider_.$get){
throw Error('provider '+name+' must define $get factory...');
}
return providerCache[name + providerSuffix] = provider_;
}Provider模式是“策略模式”+“抽象工厂模式”的混合体
- 使用$filter服务
- $filter是用来进行数据格式化的专用服务
- AngularJS内置了9个filter:
currency(格式化货币),data(日期),filter,json,limitTo,lowercase,number,orderBy,uppercase
- filter可以嵌套使用(用管道符号|分隔)
- filter是可以传递参数的
- 用户可以定义自己的filter
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="../test01/js/angular.js"></script>
</head>
<body>
{{ 1304375948024 | date}}
<br>
{{ 1304375948024 | date:"MM/dd/yy @ h:mma"}}
<br>
{{ 1304375948024 | date:"yyyy-MM-dd hh:mm::ss"}}
</body>
<script type="text/javascript">
var myModule = angular.module("MyModule",[]);
</script>
</html>
- 其他内置的Service介绍
13. 核心原理解析
- AngularJS的启动过程分析
- 依赖注入原理分析:Provider与Injector
- 指令的执行过程分析
- $scope与双向数据绑定分析
《AngularJs实战》学习笔记(慕课网)的更多相关文章
- AngularJs学习笔记-慕课网AngularJS实战
第1章 快速上手 放弃了IE8以及以下,不支持. 4大核心特性: 1.MVC Model: 数据模型 View:视图 Controller:业务逻辑和控制逻辑 好处:职责清晰,模块化. 2.模块化 3 ...
- Redis in Action : Redis 实战学习笔记
1 1 1 Redis in Action : Redis 实战学习笔记 1 http://redis.io/ https://github.com/antirez/redis https://ww ...
- AngularJS的学习笔记(一)
声明:单纯作为我自己的学习笔记,纯是为了自己学习,上面的话都是从各处粘贴,如有冒犯,请原谅我这个小菜鸟~ AngularJS使用了不同的方法,它尝试去补足HTML本身在构建应用方面的缺陷. 使用双大括 ...
- 【JS学习】慕课网8-17编程练习 网页的返回与跳转
编程练习 制作一个跳转提示页面: 要求: 1. 如果打开该页面后,如果不做任何操作则5秒后自动跳转到一个新的地址,如慕课网主页. 2. 如果点击“返回”按钮则返回前一个页面. 代码如下: 需要注意的是 ...
- 学习Vue 入门到实战——学习笔记
闲聊: 自从进了现在的公司,小颖就再没怎么接触vue了,最近不太忙,所以想再学习下vue,就看了看vue相关视频,顺便做个笔记嘻嘻. 视频地址:Vue 入门到实战1.Vue 入门到实战2 学习内容: ...
- Elasticsearch核心技术与实战-学习笔记
学习资源: Elasticsearch中文社区日报https://elasticsearch.cn/article/ Elasticsearch 官网 https://www.elastic.co/ ...
- Linux性能优化实战学习笔记:第三十七讲
一.上节回顾 上一节,我带你一起学习了网络性能的评估方法.简单回顾一下,Linux 网络基于 TCP/IP协议栈构建,而在协议栈的不同层,我们所关注的网络性能也不尽相同. 在应用层,我们关注的是应用程 ...
- Linux性能优化实战学习笔记:第四十五讲
一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...
- 60分钟内从零起步驾驭Hive实战学习笔记
本博文的主要内容是: 1. Hive本质解析 2. Hive安装实战 3. 使用Hive操作搜索引擎数据实战 SparkSQL前身是Shark,Shark强烈依赖于Hive.Spark原来没有做SQL ...
随机推荐
- java itext 报错 com.itextpdf.text.DocumentException: Font 'STSong-Light' with 'UniGB-UCS2-H'
com.itextpdf.text.DocumentException: Font 'STSong-Light' with 'UniGB-UCS2-H' 解决方案 <dependency> ...
- docker 加速器配置目录
centos 7 : /lib/systemd/system/docker.service
- sqlserver中如何将mdf文件还原到数据库
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) C. The Tower is Going Home(思维+双指针)
https://codeforces.com/contest/1075/problem/C 题意 一个宽为1e9*1e9的矩阵中的左下角,放置一个车(车可以移动到同一行或同一列),放置一些墙,竖的占据 ...
- jquery特殊字符转义方法
//特殊字符转义function escapeJquery(srcString) { // 转义之后的结果 var escapseResult = srcString; // javascript正则 ...
- 哪些优秀的 Windows 小工具,类似 clover 或 everything
有哪些优秀的 Windows 小工具,类似 clover 或 everything? 目前已知的有everything, listary, total commander, clover, dexpo ...
- urb的处理流程
USB分析 2013年11月11日 16:06:24 阅读数:1807 转载自:http://blog.csdn.net/aaa6695798/article/details/4776202 很久 ...
- i2c_client的生成
网上很多文档都是介绍源码,包括i2c_client结构体的源码都有贴出,看上去似乎需要手动写该结构体,但实际上,i2c_client的生成是用如下方法. \arch\arm\mach-omap2/bo ...
- C#的math类的全部运算方法
Abs 返回指定数字的绝对值.Acos 返回余弦值为指定数字的角度.Asin 返回正弦值为指定数字的角度.Atan 返回正切值为指定数字的角度.Atan2 返回正切值为两个指定数字的商的角度.BigM ...
- std::string的find问题研究
https://files-cdn.cnblogs.com/files/aquester/std之string的find问题研究.pdf 目录 目录 1 1. 前言 1 2. find字符串 1 3. ...