今天继续学习服务
$compile服务
他的作用是编译一段html字符串或DOM,并把他们转换成模板和模板函数,这些模板之后可以被link到scope模板中
一个示例,注意要导入jQuery库
<body ng-app="app" ng-controller="ctrl">
<div id="container">
</div>
<script>
angular.module('app',[])
.controller('ctrl',function($scope,$compile){
$scope.msg = 'yeeku';
var compileFn = $compile('<div>{{msg}}</div>');
var dom = compileFn($scope);
dom.appendTo('#container');
});
</script>
</body>
这个用起来我感觉比较绕,最简单地说,就是先定义一个变量等于$compile(html语句),然后在定义一个变量可以等于之前的变量.($scope),最后就可以用第二个定义的变量使用appendTo去添加模板
我试了一下,直接写一连串可以
$compile('<h5>ss</h5>')($scope).appendTo('#container');
中间定义几个变量主要是方便分开使用
<body ng-app="app" ng-controller="ctrl">
请输入标题:<input type="text" ng-model="title"><br>
请输入图书:<input type="text" ng-model="item" ng-list ><br>
<div compile="content"></div>
<script type="text/javascript">
angular.module('app',[])
.directive('compile',function($compile){
return function(scope,element,attrs){
scope.$watch(
function(scope){
return scope.$eval(attrs.compile);
},
function(value){
element.html(value);
var compileFn = $compile(element.contents());
compileFn(scope);
});
}
})
.controller('ctrl',function($scope){
$scope.content = '<h3>{{title}}</h3>\
<ul>\
<li ng-repeat="item in items track by $index">{{item}}</li>\
</ul>'
});
</script>
</body>
这个编译再添加到scope对象的案例我试了很多次,都失败了
!!!!!!!!!!!!!!!!!!!日后再议
<body ng-app="app" ng-controller="ctrl" >
<input ng-model="name" ><br>
<textarea ng-model="html"></textarea><br>
<div compile="html"></div>
<script>
angular.module('app',[])
.directive('compile',function($compile){
return function(scope,element,attrs){
scope.$watch(
function(scope){
return scope.$eval(attrs.compile);
},
function(value){
element.html(value);
var compileFn = $compile(element.contents())(scope);
});
};
})
.controller('ctrl',function($scope){
$scope.name='Angular';
$scope.html='hello,{{name}}';
});
</script>
</body>
这个成功了
最后上一个也破案了,item不加s
注意,这个逗号换行只针对英文逗号,中文逗号不管用
其他的服务
$document----------包装document对象,实际表示一个jqLite或jQuery对象
$window-------------包装了window对象
$timeout-------------包装了JS的setTimeout函数
$interval-------------包装了JS的setInterval函数
$rootElement-------返回整个AngularJS应用的根元素,也就是指定了ng-app属性的元素
第一个window的案例‘’
<body ng-app="app" ng-controller="ctrl" >
<input type="text" ng-model="greeting" />
<button ng-click="doGreeting(greeting)">弹出框</button>
<script>
angular.module('app',[])
.controller('ctrl',function($scope,$window){
$scope.greeting = 'nininini';
$scope.doGreeting = function(greeting){
$window.alert(greeting);
};
});
</script>
</body>
这个比较简单,就是赋值然后绑定了一个函数,练习的意义主要在window的规范使用把window部分去掉,程序也是可以运行的,包装成$window更加的安全可靠,可以避免一些测试中会遇到的问题
然后是document
<body ng-app="app" ng-controller="ctrl">
<p>$document 标题:<b ng-bind="title"></b></p>
<p>window.document 标题:<b ng-bind="windowTitle"></b></p>
<script>
angular.module('app',[])
.controller('ctrl',function($scope,$document){
$scope.title = $document[0].title;
$scope.windowTitle = angular.element(window.document)[0].title;
});
</script>
</body>
上述代码完成了对document对象的包装,这个document对象其实我没怎么搞懂
$timeout服务的用法是
$timeout([fn],[delay],[invokeApply],[Pass])
参数解析:
fn:表示要延迟执行的函数
delay:表示要延迟的时间,以毫秒为单位
invokeApply:这是一个boolean参数,表示是否在$apply块中执行fn函数,若为true,ng也会在$apply中执行函数,ng回字形脏数据检测,也就是能立即将模型的改变更新在页面上
pass:指定了额外给fn函数的参数
<body ng-app="app">
<div ng-controller="ctrl">
{{bookName}}
</div>
<script>
angular.module('app',[])
.controller('ctrl',function($scope,$timeout){
$scope.bookName="芜湖";
$timeout(function(){
$scope.bookName = "起飞";
},5000)
.then(function(){
alert("执行完成");
});
});
</script>
</body>
5s延迟后,他会改变bookName的值,他的这个then里面调用的函数是先执行的再改变的
$interval服务
$interval(fn,delay,[count],[invokeApply],[Pass]),
参数解析:
fn:待执行函数
delay:延迟时间ms
count:执行次数,默认为0,表示无限执行
invokeApply:boolean表示是否在$apply块中执行fn
Pass:指定额外传给fn的参数
<body ng-app="app">
<div ng-controller="ctrl" >
{{count}}
</div>
<script>
angular.module('app',[])
.controller('ctrl',function($scope,$interval){
$interval(function(){
if(isNaN($scope.count)){
$scope.count = 1;
}
else{
$scope.count++;
}
},100,500)
.then(function(){
alert("执行完成");
});
});
</script>
</body>
上述代码实现了一个值从1开始不断+1,执行500次,100ms为执行延迟
这么看来好像interval完爆timeout
$parse服务
这个服务用来解析ng的表达式,解析表达式后将会返回一个表达式函数,接下里即可在不同的context环境下解析该函数,同时相同的表达式使用不同的context解析也可以得到不同的结果
<body ng-app="app">
<div ng-controller="ctrl">
<h3>{{value1}}</h3>
<h3>{{value2}}</h3>
</div>
<script>
angular.module('app',[])
.controller('ctrl',function($scope,$parse){
var expression = "'hello'+user.name";
var parseFunc = $parse(expression);
var context = {user:
{name:'AngualrJS'}
};
$scope.value1 = parseFunc(context);
var ctx = {
user:{
name:"yyyy"
}
};
$scope.value2 = parseFunc(ctx);
});
</script>
</body>
它整体就是可以实现一个写个表达式格式,然后新定义的对象能够仿前面的格式输出的效果
使用关键语句:
var express="'hello!'+user.name"; //写格式
var p=$parse(express); //定义带格式的变量
var context = {user:{name:'xx'}};
$scope.value1 = p(context);
$interpolate服务
该服务的作用是将一段带表达式的字符串编译成插值函数,该服务主要在$compile服务中使用,具体方法是:
$interpolate(text,[mustHaveExpression],[trustedContext],[allOrNothing])
参数解析:
text:需要被编译的字符串
mustHaveExpression:一个boolean值,表示被编译的字符串是否必须包含表达式
trustedContext:如果传入了该参数。则在返回插值函数之前,将先使用$scc.getTrusted(interpolatedResult,trustedContext)对返回结果做处理,具体这个函数我也没接触过,遇到再说
allOrNothing:这也是个boolean值,如果为true,那么只有当text字符串中所有表达式的值都不是undefined时,该插值函数才不会返回undefined
<body ng-app="app">
<div ng-controller="ctrl">
名字:<input ng-model="name" type="text" /><br>
<div ng-bind="interpolatedValue1"></div>
<div ng-bind="interpolatedValue2"></div>
</div>
<script>
angular.module('app',[])
.controller("ctrl",function($scope,$interpolate){
$scope.$watch("name",function(newVal,oldVal,scope){
var expr1 = $interpolate('Hell11o{{name | uppercase}}!');
$scope.interpolatedValue1 = expr1({name :newVal});
var expr2 = $interpolate('hello{{user.name}}');
$scope.interpolatedValue2 = expr2({user:newVal});
})
});
</script>
</body>
这个代码出了点问题,第二个值无法进行插值
最后一句改成下面的就可有了
$scope.interpolatedValue2 = expr2({user:{name:newVal}});
第一行是用于解析表达式的字符串,解析后得到插值函数,