==AngularJS入门系列博客仅作入门快速开发参考,深层次的内容有待补充==
<body ng-app="main">
<div ng-controller="indexController">
单价10,数量<input ng-model="num" ng-change="changeHello()" />,总价<input ng-model="total" />
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
$scope.total=$scope.num*10;
$scope.num=1;
$scope.changeHello = function() {
$scope.total=10*$scope.num
};
}]);
script>
body>
-- CSS -->
.red{color:#DD1144;}
.blue{color:#0000FF}
ng-class里面的表达式:当模型中 showRed为true时显示 .red样式,当showBlue为true时,显示 .blue样式。点击按钮,触发changeColor函数,true变false,false变true,实现动态切换css样式。
<body ng-app="main">
<div ng-controller="indexController">
<p ng-class="{'red':showRed,'blue':showBlue}">可以变色的字体p>
<button class="btn btn-primary" ng-click="changeColor()">改变颜色button>
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
$scope.showRed=true;
$scope.showBlue=false;
$scope.changeColor=function(){
$scope.showRed=!$scope.showRed;
$scope.showBlue=!$scope.showBlue;
};
}]);
script>
body>
<div ng-controller="indexController">
<p class="red" ng-show="showRed">可以变色的字体p>
<p class="blue" ng-hide="showRed">可以变色的字体p>
<button class="btn btn-primary" ng-click="changeColor()">改变颜色button>
div>
<body ng-app="main">
<div ng-controller="indexController">
<input type="text" ng-model="keyword" ng-keypress="search($event)" />
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
$scope.keyword="";
$scope.search=function($event){
if(13==$event.keyCode){
alert("正在根据 "+$scope.keyword+" 开始搜索 ... ");
}
};
}]);
script>
body>
<body ng-app="main">
<div ng-controller="indexController">
<ul>
<li ng-repeat="item in books">
{{item}}
li>
ul>
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
$scope.books=['Java','Javascript','python','Mysql'];
}]);
script>
body>
首先看几个个最简单的指令例子:
<body ng-app="main">
<div ng-controller="indexController">
<span hello>该文本被替换span> <br />
<hello>该文本被替换hello> <br />
<span class="hello">该文本被替换span><br />
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.directive('hello',function(){
return {
restrict:'ACEM',
template:'Hello Angular ... ',
replace:true,
transclude:false
};
});
script>
body>
解析:
1. 使用 directive 函数创建一个新的指令,名为hello。注意如果创建的指令名称是驼峰的。如创建指令 app.directive(‘helloWorld’,function(){ … });则在使用的时候需要用 ‘-’ 来连接,
<span hello-world>span>
app.directive('hello',function(){
return {
restrict:'ACEM',
template:'Hello Angular ... ',
replace:false,
transclude:true
};
});
当你这样使用时
<span hello>内部的文本不会被直接覆盖而被包裹到模板中带有ng-transclude指令的标签中span>
页面会显示
Hello Angular ... 内部的文本不会被直接覆盖而被包裹到模板中带有ng-transclude指令的标签中
<body ng-app="main">
<div ng-controller="indexController">
<p ng-bind="count">p>
<button class="btn btn-primary" hello>countbutton>
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
$scope.count=1;
}]);
app.directive('hello',function(){
return {
restrict:'A',
link:function(scope,element,attrs){
element.on('click',function(){
scope.$apply(function(){
scope.count++;
});
});
}
};
});
script>
body>
scope上初始化count属性并赋值1,p标签绑定count,hello指令:带有hello指令的元素绑定click事件,点击一次count加1。
解析:
link:通常在link函数中封装对dom的操作。参数:
1. scope:未直接指明scope作用域时,此scope共享controller的scope。
2. element:指标记了该指令的且由angular封装后的元素,封装了基本的方法,跟jQuery封装的用法差不多。
3. attrs:标记了该指令的元素的所有属性封装的对象。比如本例子中,标记了hello指令的button带有class属性,可以使用attrs.class 取出class属性的值。!!!注意一个坑,这个地方的属性名称会全部转成小写字母,如果你的属性名中有大写,一定要注意。
4. click函数中调用了
scope.$apply(function(){ … })
如果我们去掉这个外层的包裹,直接在click函数中写 scope.count++
;会发现页面上的count值没有变化,但是在浏览器debug js的时候发现scope中的值其实已经改变了,只是页面没有做出响应。我们可以想一下,如果我们自己来实现angular的双向数据绑定,至少要有两步:1.监听数据模型与视图的变化。2.当视图数据有变时通知model更新model数据,当model数据有变时通知视图去更新视图内容。$apply()
就是其实干这个通知的事的,具体的实现原理后面我们再探讨,他的入参是一个函数。
什么情况下需要调用这个$apply()
呢?大多数情况下无需手动调用,在使用angular自带的指令比如ng-click,angular内置的服务如$http() ``$timeout()
的时候,angular已经为我们调用了这个函数,我们使用的时候无需调用,如果手动调用反而会报错。而上面的例子我们没有使用angular的指令或服务,而是普通的事件监听,所以$apply()
需要手动调用。
<body ng-app="main">
<div ng-controller="indexController">
<p>{{username}}p>
<p hello>
{{username}}
p>
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
}]);
app.directive('hello',function(){
return {
scope:true, /*或者 scope:{} 都表示指令声明了自己独立的scope*/
restrict:'A',
controller:function($scope){
$scope.username='Mike';
}
};
});
script>
body>
还是hello指令,不同的是在自定义指令中返回的对象中设置了==scope:true==,表示声明指令的scope是私有的,并为指令创建了独立的控制器,为私有scope赋值username属性为Mike,在页面上在hello指令下取 username 是可以取到的,但是在hello指令外取的username是没有值的。
<body ng-app="main">
<div ng-controller="indexController">
<p>{{username}}p>
indexController下的scope值 <input type="text" ng-model="username" />
<p hello name="{{username}}">
指令私有scope: {{name}}
p>
div>
<script type="text/javascript" src="../js/jquery1.12.4.min.js">script>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
$scope.username="Lily";
}]);
app.directive('hello',function(){
return {
scope:{
name:'@'
},
restrict:'A',
relplace:true,
template:'指令私有scope中的值:{{name}}
',
link:function(scope,ele,attrs){
$(ele).find("button").on("click",function(){
scope.$apply(function(){
scope.name="Mike";
});
});
}
};
});
script>
body>
这个例子中引入了jQuery。
解析:将indexController的scope中的username的值传递给了自定义指令hello,input框绑定的是indexController的scope中的模型,指令我们为指令模板中的button添加点击事件,当点击按钮时,改变私有scope中name的值。
运行结果:当我们在input框中改变可以看到指令所有scope中的值也会响应变化,因为@绑定策略就是将模型的值传递给指令,字符串传递。但是当我们点击按钮改变私有scope的name的值的时候,indexController的scope是不会响应这种变化的
...
scope:{
name:'@'
...
}
...
...
<p hello name="username">
...
解析:‘=’绑定策略传递的是对象
运行结果:两个scope中模型的值是双向绑定的,改变任何一个,另一个也会响应这种变化。
<body ng-app="main">
<div ng-controller="indexController">
<p hello say="sayEnglish()">p>
div>
<script type="text/javascript" src="../js/angular-1.6.4/angular.min.js">script>
<script type="text/javascript">
var app = angular.module("main", []);
app.controller("indexController", ['$scope', function($scope) {
$scope.sayEnglish=function(){
alert('Good Morning!');
};
}]);
app.directive('hello',function(){
return {
scope:{
say:'&'
},
restrict:'A',
relplace:true,
template:''
};
});
script>
body>
解析:将外层indexController的scope中的sayEnglisg()方法传递给了指令,指令内部在调用say() 方法时,实际调用的是 sayEnglish();