搜尋
首頁web前端js教程淺析AngularJS中的指令_AngularJS

ディレクティブは、AngularJS アプリケーションの最も重要な部分です。 AngularJS はすでに非常に豊富なディレクティブのセットを提供していますが、多くの場合、アプリケーション固有のディレクティブを作成する必要があります。

AngularJS と言えば、おそらく双方向のデータ バインディングとコマンド システムが最初に思い浮かぶでしょう。これら 2 つは AngularJS の最も魅力的な側面でもあります。双方向のデータバインディングについては、あまり言うことがないような気がするので、今日は AngularJS フレームワークのコマンド体系について簡単に説明します。私も初心者なので、何か悪い情報があれば確認しました。 、ワンワンが指摘します。

命令は AngularJS の最も重要な部分であるため、フレームワーク自体には多くの命令が付属していますが、開発では通常、これらの命令ではニーズを満たせないため、いくつかの命令もカスタマイズする必要があります。この場合、AngularJS ディレクティブは HTML コードで 4 つの形式の表現を持つことができます:

1. 新しい HTML 要素として使用します。

<hello></hello>或者<hello/>

2. 要素の属性として使用します

<div hello></div>

3. 要素クラスとして使用します

<div class="hello"></div>

4. コメントとして使用します

<!--directive: hello -->

ここには罠があることに注意してください。つまり、「directive: hello」の後にスペースがなければ効果がありません。同時に、コメント メソッドは慎重に使用することをお勧めします。ハイエンドを追求する必要があります。その場合は、ただ自発的に使用してください。命令には上記の4つの表現形式がありますが、具体的にはどのように定義されるのでしょうか?

.directive('hello',function(){
return {
restrict:'AECM',
template:'<button>click me</button>'
}
})

上記は、何も除いて、命令を定義する最も単純なコードです。上記のコードでは、 directive() メソッドは新しいディレクティブを定義します。このメソッドには 2 つのパラメーターがあり、最初の 'hello' はディレクティブの名前を hello として指定し、2 番目のパラメーターはディレクティブ オブジェクトを返す関数です。したがって、上記のコードでは、関数は主に 2 つの属性を使用してこの hello 命令を定義します:

1.strict[string] 属性は主に、命令が HTML コードで使用できる表現形式を指定するために使用されます。 A は属性、E は要素、C はクラス、M はアノテーションを表します。実際の場面では、AE という 2 つの方法が一般的に使用されます。

2. template[string or function] 属性は、Angular によって命令がコンパイルおよびリンクされた後に生成される HTML マークアップを指定します。この属性は、HTML テキストを 1 つだけ含めるという単純なものにすることも、非常に複雑にすることもできます。属性の値が関数の場合、メソッドはテンプレートを表す文字列を返します。式 {{}} もその中で使用できます。

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 () {
return{
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属性的时候,我们可以这样写:

scope{
color:'@color'
}
<hello color="{{color}}"></hello>

这里有两点需要注意:1、scope里的属性color代表的是模板{{}}这个表达式里面的color,两者必须一致。2、scope里的属性color的值,也就是@后面的color,表示的是下面的HTML元素里的属性color,所以这两者也必须一致,当这里的属性名和模板里表达式{{}}里面使用的名称相同的话,就可以省略掉@后面的属性名了,然后写成下面的形式。

scope{
color:'@'
}

从指令中scope的值可以看出,指令模板中的表达式{{}}里的color的指向的是当前元素元素的color属性,这个color属性的值就是父scope的属性color的值。父scope把他的color属性值传递给了当前元素的color属性,然后color属性又把值传递给了模板中表达式里的color,这个过程是单向的。

二:使用=实现双向绑定

.directive('hello', function () {
return{
restrict:'AECM',
replace:true,
template:'<button style="background-color: {{color}}">click me</button>',
scope:{
color:'='
},
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 () {
return{
restrict:'AECM',
replace:true,
template:'<button ng-click="sayhello()" style="background-color: {{color}}">click me</button>',
scope:{
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 () {
return{
restrict:'AECM',
replace:true,
transclude:true,
scope:{},
template:'<div ng-transclude></div>',
}
})
<hello>
hello
<span>{{color}}</span>
</hello>

当他的值为true的时候,这是页面上输出的值。当为false的时候,页面上将会是空白的。这里有一个地方需要注意,就是{{color}},这里的color是父scope里的color。并不是指令里的scope的color属性。

7、compile[function]参数,该方法有两个参数element,attrs,第一个参数element指指令所在的元素,第二个attrs指元素上赋予的参数的标准化列表。这里我们也有个地方需要注意:compile 函数不能访问 scope,并且必须返回一个 link 函数。但是如果没有设置 compile 函数,你可以正常地配置 link 函数,(有了compile,就不能用link,link函数由compile返回)。

.directive('hello', function () {
return{
restrict:'AECM',
replace:true,
translude:true,
template:'<button ng-click="sayhello()" style="background-color: {{color}}">click me</button>',
scope:{
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过来的。原文在这里http://blog.jobbole.com/62249/)。

9、controller[string or function]和require[string or string[]]参数,当我们想要允许其他的指令和你的指令发生交互时,我们就需要使用 controller 函数。当另一个指令想要交互时,它需要声明它对你的指令 controller 实例的引用(require)。

.directive('hello', function () {
return{
scope:{},
require:'^he',
compile: function (element,attrs) {
return function (scope,elements,attrs,cntIns) {
cntIns.fn()
};
}
}
})
.directive('he', function () {
return {
restrict:'AE',
scope:{},
controller: function ($scope, $compile, $http) {
this.fn= function () {
alert('hello');
};
}
}
})
<he>
<hello color="color" sayhello="sayhello()"></hello>
</he>

当页面加载完毕之后,会弹出一个对话框。

好了上面就是我这段时间学习angular,所了解到的指令的知识,就先写到这里了。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境