为什么各种小细节走到跟前才夜神模拟器加载到99出来

AngularJS中的指令全面解析(必看)
投稿:jingxian
字体:[ ] 类型:转载 时间:
下面小编就为大家带来一篇AngularJS中的指令全面解析(必看)。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方。双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJS这个框架的指令系统,本人也是初学,查阅了一些资料,要是有一些说的不好的地方,万望指出。
指令作为AngularJS中最为重要的部分,所以这个框架本身也是自带了比较多的的指令,但是在开发中,这些指令通常不能满足我们的需要,所以我们也是需要自定义一些指令的。那么一个AngularJS指令在HTML代码中可以有四种表现形式:
1、作为一个新的HTML元素来使用。
&hello&&/hello&或者&hello/&
2、作为一个元素的属性来使用
&div hello&&/div&
3、作为一个元素的类来使用
&div class="hello"&&/div&
4、作为注释来使用
&!--directive: hello --&
注意这里有一个陷阱,就是在“directive: hello”这个的后面要有一个空格,不然的话是没有效果的,同时推荐注释的方法的还是少用,如果非要追求高大上,那就随性吧。既然指令有以上四种表现形式,那么具体他是怎么来定义的呢?
.directive('hello',function(){
restrict:'AECM',
template:'&button&click me&/button&'
上面就是定义一个指令最简单的代码了,没有之一。在上面的代码中,directive()这个方法定义了一个新的指令,该方法有两个参数,第一个'hello'就是规定指令的名字为hello,第二个参数是返回指令对象的函数。那么在上面的代码中,该函数主要使用了两个属性来定义这个hello指令:
1、restrict[string]这个属性,主要是用来规定指令在HTML代码中可以使用什么表现形式。A代表属性、E代表元素、C代表类、M代表注释。实际情况中我们一般使用AE这两种方式。
2、template[string or function]这个属性,规定了指令被Angular编译和链接(link)后生成的HTML标记,这个属性可以简单到只有一个HTML文本在里面,也可以特别复杂,当该属性的值为function的时候,那么该方法返回的就是代表模板的字符串,同时也可以在里面使用{{}}这个表达式。
template: function () {
return '&button&click me&/button&';
但是在一般情况下,template这个属性都会被templateUrl取代掉,用它来指向一个外部的文件地址,所以我们通常把模板放在外部的一个HTML文件中,然后使用templateUrl来指向他。
在定义指令的时候,除了以上两个最基础的属性外,我们还会使用到其他的很多属性,那么下面我们就来一一的说下:
1、priority[number]属性,这个属性是来规定自定义的指令的优先级的,当一个DOM元素上面有一个以上的指令的时候,就需要去比较指令的优先级了,优先级高的指令先执行。这个优先级就是用来在执行指令的compile函数前,先排序的,那么关于compile这个函数,我们会在下面仔细的说下。
2、terminal[boolean]属性,该参数用来定义是否停止当前元素上比本指令优先级低的指令,如果值为true,就是正常情况,按照优先级高低的顺序来执行,如果设置为false,就不会执行当前元素上比本指令优先级低的指令。
3、replace[boolean]属性,这个属性用来规定生成的HTML内容是否会替换掉定义此指令的HTML元素。当我们把该属性的值设为true的时候,打开控制台看看你会发现这个指令生成的元素会是这样的:
当我们设置为false的时候会是这样的:
4、link[function]属性,在上面的例子中,我们自定义的指令其实没有多大意义,这只是一个最简单的指令,有好多的属性我们都没有为他定义,所以没有多大用途。比如这个link函数,它包括三个参数:scope、element、attrs。这个link函数主要是用来添加对DOM元素的事件监听、监视模型属性变化、以及更新DOM的。它里面三个参数:
一:scope参数,在我们没有为指令定义scope属性的时候,那么他代表的就是父controller的scope。
二:element参数,就是指令的jQLite(jQuery的子集)包装DOM元素。如果你在引入AngularJS之前引入了jQuery,那么这个元素就是jQuery元素,而不是jQLite元素。由于这个元素已经被jQuery/jQLite包装了,所以我们就在进行DOM操作的时候就不需要再使用 $()来进行包装。
三:attrs参数,它包含了该指令所在元素的属性的标准化参数对象。
5、scope[boolean or object]属性,该属性是用来定义指令的scope的范围,默认情况下是false,也就是说该指令继承了父controller的scope,可以随意的使用父controller的scope里的属性,但是这样的话就会污染到父scope里的属性,这样是不可取的。所以我们可以让scope取以下两个值:true和{}。
当为true的时候,表示让Angular给指令创建一个继承于父scope的scope。
var myapp=angular.module('myapp',[])
.controller('myctrl',['$scope', function ($scope) {
$scope.color='red';
.directive('hello', function () {
restrict:'AECM',
replace:true,
template:'&button ng-click="sayhello()" style="background-color: {{color}}"&click me&/button&',
scope:true,
link: function (scope,elements,attrs) {
elements.bind('click', function () {
elements.css('background-color','blue');
这里我们为父scope定义了一个color的属性,并赋值为red,在hello指令的scope属性中,我们给了true,所以angular就为这个指令创建了一个继承于父scope的scope,然后在template属性中,我们用{{}}使用了从父scope中继承过来的color属性,所以按钮会是红色的。
当为{}的时候,表示创建一个隔离的scope,不会继承父scope的属性。但是在有的时候我们也要需要访问父scope里的属性或者方法,那么我们应该怎么办呢。angular早就为我们想到了这一点,有以下的三个办法可以让我们记性上面的操作:
一:使用@实现单向绑定,如果我们只给scope的这个{}值的话,那么上面代码的按钮的背景色将会是灰色的。,而如果我们需要使用父scope的color属性的时候,我们可以这样写:
color:'@color'
&hello color="{{color}}"&&/hello&
这里有两点需要注意:1、scope里的属性color代表的是模板{{}}这个表达式里面的color,两者必须一致。2、scope里的属性color的值,也就是@后面的color,表示的是下面的HTML元素里的属性color,所以这两者也必须一致,当这里的属性名和模板里表达式{{}}里面使用的名称相同的话,就可以省略掉@后面的属性名了,然后写成下面的形式。
从指令中scope的值可以看出,指令模板中的表达式{{}}里的color的指向的是当前元素元素的color属性,这个color属性的值就是父scope的属性color的值。父scope把他的color属性值传递给了当前元素的color属性,然后color属性又把值传递给了模板中表达式里的color,这个过程是单向的。
二:使用=实现双向绑定
.directive('hello', function () {
restrict:'AECM',
replace:true,
template:'&button style="background-color: {{color}}"&click me&/button&',
link: function (scope,elements,attrs) {
elements.bind('click', function () {
elements.css('background-color','blue');
scope.$apply(function () {
scope.color='pink';
&hello color="color"&&/hello&
&input type="text" ng-model="color"/&
这里我们给指令的scope中的color属性和父scope中的color属性进行了双向绑定,并且给指令的link函数里,添加了一个单击事件,点击按钮会让按钮的颜色发生变化,并且改变指令scope的color属性的值,再给HTML页面中加了一个input标签,输出或者输入父scope的color属性的值。这里有一个地方需要注意:当前元素的属性名的值不用再加上{{}}这个表达式了,因为这里父scope传递的是一个真实的scope数据模型,而不是简单的字符串,所以这样我们就可以传递简单的字符串、数组、甚至复杂的对象给指令的scope。现在让我们来看看点击这个按钮将会发生什么。
这里我们能看到,按钮的颜色变成了粉色的,说明点击让指令的scope的color属性发生了变化,从而导致按钮的颜色发生了变化。但是这里不仅仅是按钮发生了变化,注意看,input表单里的值也变成了pink,这就说明父scope的color属性也发生了变化。 另外,再让我们来给input里面输入一个颜色,看看发生什么变化。
,可以看出当我们在表单里输入另外一种颜色的时候,按钮的颜色也发生了变化,这就说明指令的scope的color属性被改变了。综上我们可以发现使用'='实现的是双向绑定。
三:使用&调用父scope里的方法
var myapp=angular.module('myapp',[])
.controller('myctrl',['$scope', function ($scope) {
$scope.color='red';
$scope.sayhello= function () {
alert('hello');
.directive('hello', function () {
restrict:'AECM',
replace:true,
template:'&button ng-click="sayhello()" style="background-color: {{color}}"&click me&/button&',
color:'=',
sayhello:'&'
link: function (scope,elements,attrs) {
elements.bind('click', function () {
elements.css('background-color','blue');
scope.$apply(function () {
scope.color='pink';
&hello color="color" sayhello="sayhello()"&&/hello&
&input type="text" ng-model="color"/&
这里我们也有两个地方需要注意:1、我们不仅需要在模板中使用ng-click指令,绑定上要调用的父scope中的方法,而且要在给当前元素添加一个属性,并且这个属性指向要调用的父scope的方法。2、指令scope的属性sayhello、当前元素的属性sayhello、模板绑定的事件方法名sayhello这三者要一致。那么这样我们就可以点击按钮,弹出一个对话框了。
6、transclude[boolean]属性,这个属性用来让我们规定指令是否可以包含任意内容
.directive('hello', function () {
restrict:'AECM',
replace:true,
transclude:true,
template:'&div ng-transclude&&/div&',
&span&{{color}}&/span&
当他的值为true的时候,这是页面上输出的值。当为false的时候,页面上将会是空白的。这里有一个地方需要注意,就是&span&{{color}}&/span&,这里的color是父scope里的color。并不是指令里的scope的color属性。
7、compile[function]参数,该方法有两个参数element,attrs,第一个参数element指指令所在的元素,第二个attrs指元素上赋予的参数的标准化列表。这里我们也有个地方需要注意:compile 函数不能访问 scope,并且必须返回一个 link 函数。但是如果没有设置 compile 函数,你可以正常地配置 link 函数,(有了compile,就不能用link,link函数由compile返回)。
.directive('hello', function () {
restrict:'AECM',
replace:true,
translude:true,
template:'&button ng-click="sayhello()" style="background-color: {{color}}"&click me&/button&',
color:'=',
sayhello:'&'
compile: function (element,attrs) {
return function (scope,elements,attrs) {
elements.bind('click', function () {
elements.css('background-color','blue');
scope.$apply(function () {
scope.color='pink';
现在让我们来点击这个按钮
我们发现,这里点击按钮之后发生的事情和前面用link属性的一样,这其实是没有多少差别的。
其实在大多数的情况下,我们只需要使用 link 函数。这是因为大部分的指令只需要考虑注册事件监听、监视模型、以及更新DOM等,这些都可以在 link 函数中完成。 但是对于像 ng-repeat 之类的指令,需要克隆和重复 DOM 元素多次,在 link 函数执行之前由 compile 函数来完成。那么为什么我们需要两个分开的函数来完成生成过程,为什么不能只使用一个?要回答好这个问题,我们需要理解指令在Angular中是如何被编译的!
8、指令是如何被编译的
当我们的angular应用引导启动的时候,angular将会使用$compile服务遍历DOM元素,在所有的指令都被识别之后,将会调用指令的compile方法,返回一个link函数,然后将这个link函数添加到稍后执行的 link 函数列表中,这个过程被称为编译阶段。像ng-repeat这样的指令,需要被重复克隆很多次,compile函数只在编译阶段被执行一次,并且复制这些模板,但是link 函数会针对每个被复制的实例被执行。所以分开处理,让我们在性能上有一定的提高(这句话有点不太理解,我是从别的地方copy过来的。
9、controller[string or function]和require[string or string[]]参数,当我们想要允许其他的指令和你的指令发生交互时,我们就需要使用 controller 函数。当另一个指令想要交互时,它需要声明它对你的指令 controller 实例的引用(require)。
.directive('hello', function () {
require:'^he',
compile: function (element,attrs) {
return function (scope,elements,attrs,cntIns) {
cntIns.fn()
.directive('he', function () {
restrict:'AE',
controller: function ($scope, $compile, $http) {
this.fn= function () {
alert('hello');
&hello color="color" sayhello="sayhello()"&&/hello&
当页面加载完毕之后,会弹出一个对话框。
好了上面就是我这段时间学习angular,所了解到的指令的知识,就先写到这里了。
以上这篇AngularJS中的指令全面解析(必看)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具推荐这篇日记的豆列
······&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Search:&&&&Sort by:&&&&& ng-model=&orderProp&&&&&&&&name&&&&&&age&&&&&&&&&&&&&&&&&&&&&&&&&&{{stu.name}}&&&&&&&&{{stu.address}}&&&&&&&&{{stu.age}}&&&&&&&&&&&&&可以看到,实现上述功能,需要的所有HTML/JS代码加起来不到40行,代码是很简洁的,很清晰。如果不使用angularJS,我们使用JavaScript和jQuery来完成上述功能,我们必须要做的事情如下:1、给search和sort 这2个控件,绑定事件处理函数。当搜索条件或者排序改变的时候,能够实时刷新学生信息列表。2、由于有排序,所以必须要编写选择排序或冒泡等排序算法,需要考虑字符串比较和数字比较这2种情况。3、在JS中,通过字符串拼接的方式将插入到DOM中。写过这种代码的都知道,JS中进行HTML字符串的拼接,非常的复杂。可以看到使用传统的JS开发方式,有很多重复繁琐的劳动,如事件处理函数的绑定、复杂的html字符串拼接等。通过这个例子,很明显可以看到使用angularJS开发效率远远高于JQuery和这种传统的开发方式。如果你还没有感受到angularJS的强大和吸引力,那么我们再看一下关于angular的产生背景。下面是来自 &大漠穷秋译作《用AngularJS开发下一代Web应用》的前言。“关于Angular 的起源,我可以追溯到2009 年的Google Feedback &项目。当时,对于项目的开发速度以及如何编写可测试代码的问题,我们已经经受了几个月的折磨。6 个月时,我们开发了差不多17000 &行前端代码。这时候,团队中的一个成员Misko Hevery &做出了一个大胆的宣言:利用他自己业余时间所开发的一个开源库,他可以在两周之内把目前所有东西重写一遍。我当时想,两周的时间并不会给我们造成太大的影响,同时我们也接受了Misko 努力构建一些东西的想法。然而Misko &最终还是估算错了时间,他用了三个星期。但是,我们所有人还是被他深深地震撼了,更让我们感到震撼的是,他所开发的新应用的代码量从原来的17000 &行压缩到了1500 行。看起来,Misko 的东西值得深入推广。Misko &和我决定,围绕他所提倡的理念组建一个团队,这个简单的理念就是:简化对web 开发者的经验要求。”通过上面的背景介绍,可以看到angular确实能够极大的减少代码量,提高开发效率。行文至此,如果还是没有激起您对angularJS的兴趣和好奇,那么是我语言组织和表达能力不行,不是angular不行。没有了
上一页:没有了 &&&&&下一页:相关内容
暂无与此文章相关内容最新内容【前端——工作小问题】(9)
今天碰到一个问题,刷新页面时,会短暂出现未渲染的代码,大约一分钟,如下:
{{record.name}}
{{record.state}}
原因暂时还没搞清楚,代码和其他页面一样,但是其他页面不会出现这个问题,在思考有没有可能是因为当前页面的代码量过少导致和其他页面的差异现象。
解决方法,在&ng-controller 所在的标签中加入 ng-cloak
上给出的ng-cloak的解释为:
ng-cloak 指令用于在 AngularJS 应用在加载时防止 AngularJS 代码未加载完而出现的问题。
AngularJS 应用在加载时,文档可能会由于AngularJS 代码未加载完而出现显示 AngularJS 代码,进而会有闪烁的效果,
ng-cloak 指令是为了防止该问题的发生。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场00:50 提问
angularjs,代码完全从w3cschool里扒下来的但是不起作用
&!DOCTYPE html&
&div ng-app="" ng-controller="customersController"&
&li ng-repeat="x in names"&
{{ x.Name + ', ' + x.Country }}
function customersController($scope,$http) {
$http.get("/try/angularjs/data/Customers_JSON.php")
.success(function(response) {$scope.names =});
&script src="/libs/angular.js/1.2.15/angular.min.js"&&/script&
就是这个代码,想试试$http 获取json数据来着,但就是无法显示
困扰好久了
浏览器的控制审查报错
已阻止跨源请求:同源策略禁止读取位于
的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
如果设置路径为本地json的话,完全没有反应
求教啊求教
按赞数排序
跨域了,并且
这个地址不允许跨域请求,当然会报错。可以用雅虎的,Yahoo这个地址允许跨域请求,不过注意设置Access-Control-Allow-Origin为*允许跨域,IE跨域对象是XDomaiRequest对象,XMLHttpRequest对象只有IE11才支持
&!DOCTYPE html&
&div ng-app="" ng-controller="customersController"&
&li ng-repeat="x in names"&
{{ x.Name + ', ' + x.Country }}
function customersController($scope, $http) {
method:'GET',
url: "/v1/public/yql",
q: "select * from json where url=\"/try/angularjs/data/Customers_JSON.php\"",
format: "json"
}).success(function (response) {
console.log(response)
$scope.names = response.query.results.json.
&script src="/libs/angular.js/1.2.15/angular.min.js"&&/script&
file和http不是同一个域,最好的是在本地搭一个环境,用Apache之类的
不是本地,而是你应该部署到同一个域下。
跨域了,本地搭建web应用服务器(apache、tomcat、iis之类)。
推荐下个wampserver2.5集成包,在本地搭建一个服务器,然后点击右下角wamp图标,点击www,在里面创建一个文件夹,如:test,把你的代码
文件都放进去
修改为http://localhost/test/Customers_JSON.php
其他相似问题

我要回帖

更多关于 滚动到底部加载更多 的文章

 

随机推荐