Rumah  >  Artikel  >  Tutorial CMS  >  Tingkatkan HTML dengan arahan AngularJS

Tingkatkan HTML dengan arahan AngularJS

王林
王林asal
2023-08-27 08:01:15720semak imbas

使用 AngularJS 指令增强 HTML

Ciri utama AngularJS ialah ia membolehkan kami memperluaskan fungsi HTML untuk memenuhi tujuan halaman web dinamik hari ini. Dalam artikel ini, saya akan menunjukkan kepada anda cara menggunakan arahan AngularJS untuk menjadikan pembangunan anda lebih pantas dan lebih mudah serta menjadikan kod anda lebih mudah diselenggara.

Sediakan

Langkah 1: Templat HTML

Untuk memudahkan urusan, kami akan menulis semua kod dalam fail HTML. Cipta dan letakkan templat HTML asas ke dalamnya:

<!DOCTYPE html> <html> <head> </head> <body> </body> </html>

Sekarang tambahkan fail angular.min.js daripada Google CDN pada dokumen: angular.min.js 文件添加到文档的 中:

 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>

第 2 步:创建模块

现在让我们为指令创建模块。我将其称为 example,但您可以选择任何您想要的名称,只需记住我们将使用此名称作为稍后创建的指令的命名空间。

将此代码放在 底部的脚本标记中:

var module = angular.module('example', []);

我们没有任何依赖项,因此 angular.module() 的第二个参数中的数组为空,但不要完全删除它,否则您将得到 $injector:nomod错误,因为 angular.module() 的单参数形式检索对已存在模块的引用,而不是创建新模块。

您还必须将 ng-app="example" 属性添加到 标记才能使应用程序正常工作。之后文件应如下所示:

<!DOCTYPE html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> <script> var module = angular.module('example', []); </script> 
    </head> 
    <body ng-app="example"> 
    </body> 
</html>

属性指令:1337 C0NV3R73R

首先,我们将创建一个简单的指令,其工作方式与 ngBind 类似,但它将把文本更改为 leet talk。

第 1 步:指令声明

使用 module.directive() 方法声明指令:

module.directive('exampleBindLeet', function () {

第一个参数是指令的名称。它必须采用驼峰式命名法,但由于 HTML 不区分大小写,因此您将在 HTML 代码中使用破折号分隔的小写形式 (example-bind-leet)。

作为第二个参数传递的函数必须返回一个描述该指令的对象。目前它只有一个属性:链接函数:

    return {
		link: link
	};
});

第2步:链接函数

您可以在 return 语句之前定义函数,也可以直接在返回的对象中定义该函数。它用于操作我们的指令所应用的元素的 DOM,并使用三个参数进行调用:

function link($scope, $elem, attrs) {

$scope 是一个 Angular 范围对象,$elem 是该指令匹配的 DOM 元素(它包装在 jqLit​​e 中,jqLit​​e 是 AngularJS 的 jQuery 最常用函数的子集) attrs 是一个具有所有元素属性的对象(具有规范化名称,因此 example-bind-leet 将可用作 attrs.exampleBindLeet)。

我们的指令中此函数的最简单的代码如下所示:

    var leetText = attrs.exampleBindLeet.replace(/[abegilostz]/gmi, function (letter) {
	    return leet[letter.toLowerCase()];
    });

	$elem.text(leetText);
}

首先,我们将 example-bind-leet 属性中提供的文本中的一些字母替换为 leet 表中的替换内容。该表如下所示:

var leet = {
    a: '4', b: '8', e: '3',
	g: '6', i: '!', l: '1',
	o: '0', s: '5', t: '7',
	z: '2'
};

您应该将其放在 <script></script> 标记的顶部。正如您所看到的,这是最基本的 leet 转换器,因为它仅替换十个字符。

之后,我们将字符串转换为 leet say,我们使用 jqLit​​e 的 text() 方法将其放入该指令匹配的元素的内部文本中。

现在您可以通过将此 HTML 代码放入文档的 中来测试它:

<div example-bind-leet="This text will be converted to leet speak!"></div>

输出应如下所示:

但这并不完全是 ngBind 指令的工作原理。我们将在接下来的步骤中改变这一点。

第 3 步:范围

首先,example-bind-leet 属性中传递的应该是对当前作用域中变量的引用,而不是我们要转换的文本。为此,我们必须为指令创建一个隔离的范围。

我们可以通过将作用域对象添加到指令函数的返回值来实现这一点:

module.directive('exampleBindLeet', function () {
    ...
	return {
		link: link,
		scope: {

		}
	};
);

该对象中的每个属性都将在指令的范围内可用。它的值将由这里的值决定。如果我们使用“-”,则该值将等于与属性同名的属性的值。使用“=”将告诉编译器我们期望传递当前作用域中的变量 - 这将像 ngBind:

一样工作
scope: {
	exampleBindLeet: '='
}

您还可以使用任何内容作为属性名称,并将规范化(转换为驼峰命名法)的属性名称放在 - 或 = 后面:

scope: {
	text: '=exampleBindLeet'
}

选择最适合您的。现在我们还必须更改链接函数以使用 $scope 而不是 attr

function link($scope, $elem, attrs) {
    var leetText = $scope.exampleBindLeet.replace(/[abegilostz]/gmi, function (letter) {
		return leet[letter.toLowerCase()];
	});

	$elem.text(leetText);
}

🎜Langkah 2: Buat Modul🎜🎜 🎜Sekarang mari buat modul untuk arahan. Saya akan memanggilnya contoh tetapi anda boleh memilih mana-mana nama yang anda mahu, cuma ingat bahawa kami akan menggunakan nama ini sebagai ruang nama untuk arahan yang kami buat kemudian. 🎜 🎜Letakkan kod ini dalam teg skrip di bahagian bawah : 🎜
 <body ng-app="example" ng-init="textToConvert = 'This text will be converted to leet speak!'"> 
    <div example-bind-leet="textToConvert"></div> 
</body> 
🎜Kami tidak mempunyai sebarang kebergantungan, jadi tatasusunan dalam parameter kedua angular.module() adalah kosong, tetapi jangan alih keluar sepenuhnya atau anda akan mendapat $injector :nomod Ralat kerana bentuk hujah tunggal angular.module() mendapatkan semula rujukan kepada modul sedia ada dan bukannya mencipta modul baharu. 🎜 🎜Anda juga mesti menambahkan atribut ng-app="example" pada teg agar apl berfungsi dengan baik . Fail itu sepatutnya kelihatan seperti ini: 🎜
<input ng-model="textToConvert">
🎜🎜Arahan atribut: 1337 C0NV3R73R🎜🎜 🎜Pertama, kami akan mencipta arahan mudah yang akan berfungsi sama seperti ngBind, tetapi ia akan menukar teks kepada leet talk. 🎜 🎜🎜Langkah 1: Kenyataan Arahan🎜🎜 🎜Gunakan kaedah module.directive() untuk mengisytiharkan arahan: 🎜
function link($scope, $elem, attrs) {
    function convertText() {
		var leetText = $scope.exampleBindLeet.replace(/[abegilostz]/gmi, function (letter) {
			return leet[letter.toLowerCase()];
		});

		$elem.text(leetText);
	}
}
🎜Parameter pertama ialah nama arahan. Ia mestilah dalam camelCase, tetapi memandangkan HTML tidak sensitif huruf besar-besaran, anda akan menggunakan huruf kecil yang dibataskan sempang (example-bind-leet) dalam kod HTML. 🎜 🎜Fungsi yang diluluskan sebagai argumen kedua mesti mengembalikan objek yang menerangkan arahan. Pada masa ini ia hanya mempunyai satu atribut: fungsi pautan: 🎜
$scope.$watch('exampleBindLeet', convertLeet);
🎜🎜Langkah 2: Pautan fungsi🎜🎜 🎜Anda boleh menentukan fungsi sebelum pernyataan pemulangan atau terus dalam objek yang dikembalikan. Ia digunakan untuk memanipulasi DOM elemen yang digunakan oleh arahan kami, dan dipanggil dengan tiga parameter: 🎜
example-progress {
    display: block;
	width: 100%;
	position: relative;
	border: 1px solid black;
	height: 18px;
}

example-progress .progressBar {
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	background: green;
}

example-progress .progressValue {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	text-align: center;
}
🎜$scope ialah objek Angular skop, $elem ialah elemen DOM yang dipadankan dengan arahan ini (ia dibalut dengan jqLite​ ​​jqLite ialah subset daripada fungsi jQuery yang paling biasa digunakan untuk AngularJS) attrs ialah objek dengan semua atribut elemen (dengan nama berkanun, jadi example-bind-leet akan Tersedia sebagai attrs.exampleBindLeet). 🎜 🎜Kod paling mudah untuk fungsi ini dalam arahan kami kelihatan seperti ini: 🎜
module.directive('exampleProgress', function () {
    return {
		restrict: 'E',
		scope: {
			value: '=',
			max: '='
		},
		template: '',
		link: link
	};
});
🎜Mula-mula, kami menggantikan beberapa huruf dalam teks yang disediakan dalam atribut example-bind-leet dengan kandungan gantian daripada jadual leet. Jadualnya kelihatan seperti ini: 🎜
<div class="progressBar"></div><div class="progressValue">{{ percentValue }}%</div>
🎜Anda harus meletakkannya di atas teg <script></script>. Seperti yang anda lihat, ini adalah penukar leet paling asas kerana ia hanya menggantikan sepuluh aksara. 🎜 🎜Selepas itu, kami menukar rentetan kepada leet say, yang kami gunakan kaedah text() jqLite untuk dimasukkan ke dalam teks dalaman elemen yang dipadankan dengan arahan ini. 🎜 🎜Kini anda boleh menguji kod HTML ini dengan meletakkannya dalam dokumen anda: 🎜
function link($scope, $elem, attrs) {
    function updateProgress() {
		var percentValue = Math.round($scope.value / $scope.max * 100);
		$scope.percentValue = Math.min(Math.max(percentValue, 0), 100);
		$elem.children()[0].style.width = $scope.percentValue + '%';
	}
}
🎜Keluaran sepatutnya kelihatan seperti ini: 🎜 🎜Tetapi bukan itu cara arahan ngBind berfungsi. Kami akan mengubahnya dalam langkah seterusnya. 🎜 🎜🎜Langkah 3: Skop🎜🎜 🎜Pertama sekali, apa yang diluluskan dalam atribut example-bind-leet hendaklah merujuk kepada pembolehubah dalam skop semasa, bukan teks yang ingin kita tukar. Untuk melakukan ini, kita perlu mencipta skop terpencil untuk arahan tersebut. 🎜 🎜Kita boleh mencapai ini dengan menambahkan objek skop pada nilai pulangan fungsi arahan: 🎜
$scope.$watchCollection('[value, max]', updateProgress);
🎜Setiap harta dalam objek akan tersedia dalam skop arahan. Nilainya akan ditentukan oleh nilai di sini. Jika kita menggunakan "-", nilainya akan sama dengan nilai atribut dengan nama yang sama. Menggunakan "=" akan memberitahu pengkompil yang kami jangkakan untuk lulus pembolehubah dalam skop semasa - ini akan berfungsi seperti ngBind:🎜
<body ng-app="example" ng-init="textToConvert = 'This text will be converted to leet speak!'; progressValue = 20; progressMax = 100">
🎜Anda juga boleh menggunakan apa sahaja sebagai nama harta dan meletakkan nama harta benda yang dinormalisasi (ditukar kepada camelCase) selepas - atau =: 🎜
<example-progress value="progressValue" max="progressMax"></example-progress>
🎜Pilih yang paling sesuai dengan anda. Kini kita juga perlu menukar fungsi pautan untuk menggunakan $scope dan bukannya attr: 🎜
function link($scope, $elem, attrs) {
    var leetText = $scope.exampleBindLeet.replace(/[abegilostz]/gmi, function (letter) {
		return leet[letter.toLowerCase()];
	});

	$elem.text(leetText);
}

现在使用 ngInit 或创建一个控制器,并将 divexample-bind-leet 属性的值更改为您使用的变量的名称:

 <body ng-app="example" ng-init="textToConvert = 'This text will be converted to leet speak!'"> 
    <div example-bind-leet="textToConvert"></div> 
</body> 

第 4 步:检测更改

但这仍然不是 ngBind 的工作原理。要查看我们添加一个输入字段以在页面加载后更改 textToConvert 的值:

<input ng-model="textToConvert">

现在,如果您打开页面并尝试更改输入中的文本,您将看到我们的 div 中没有任何变化。这是因为 link() 函数在编译时每个指令都会调用一次,因此它无法在每次范围内发生更改时更改元素的内容。

要改变这一点,我们将使用 $scope.$watch() 方法。它接受两个参数:第一个是 Angular 表达式,每次修改范围时都会对其进行求值,第二个是回调函数,当表达式的值发生更改时将被调用。

首先,让我们将 link() 函数中的代码放入其中的本地函数中:

function link($scope, $elem, attrs) {
    function convertText() {
		var leetText = $scope.exampleBindLeet.replace(/[abegilostz]/gmi, function (letter) {
			return leet[letter.toLowerCase()];
		});

		$elem.text(leetText);
	}
}

现在,在该函数之后,我们将调用 $scope.$watch(),如下所示:

$scope.$watch('exampleBindLeet', convertLeet);

如果您现在打开页面并更改输入字段中的某些内容,您将看到 div 的内容也按预期发生了变化。

元素指令:进度条

现在我们将编写一个指令来为我们创建一个进度条。为此,我们将使用一个新元素:<example-progress></example-progress>

第 1 步:样式

为了让我们的进度条看起来像一个进度条,我们必须使用一些 CSS。将此代码放入文档的 中的 <style></style> 元素中:

example-progress {
    display: block;
	width: 100%;
	position: relative;
	border: 1px solid black;
	height: 18px;
}

example-progress .progressBar {
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	background: green;
}

example-progress .progressValue {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	text-align: center;
}

正如你所看到的,它非常基本 - 我们使用 position:relativeposition:absolute 的组合来定位绿色条和 <example-progress></example-progress> 元素。

第 2 步:指令的属性

与前一个相比,这个需要更多的选项。看一下这段代码(并将其插入到您的 <script></script> 标记中):

module.directive('exampleProgress', function () {
    return {
		restrict: 'E',
		scope: {
			value: '=',
			max: '='
		},
		template: '',
		link: link
	};
});

正如您所看到的,我们仍然使用范围(这次有两个属性 - value 表示当前值,max 表示最大值)和 link() 函数,但有两个新属性:

  • restrict: 'E' - 这告诉编译器查找元素而不是属性。可能的值为:
    • 'A' - 仅匹配属性名称(这是默认行为,因此如果您只想匹配属性,则无需设置它)
    • 'E' - 仅匹配元素名称
    • 'C' - 仅匹配类名
  • 您可以将它们组合起来,例如“AEC”将匹配属性、元素和类名称。
  • template: '' - 这允许我们更改元素的内部 HTML(如果您想从单独的文件加载 HTML,还有 templateUrl)

当然,我们不会将模板留空。将此 HTML 放在那里:

<div class="progressBar"></div><div class="progressValue">{{ percentValue }}%</div>

如您所见,我们还可以在模板中使用 Angluar 表达式 - percentValue 将从指令的范围中获取。

第3步:链接函数

该函数与上一个指令中的函数类似。首先,创建一个将执行指令逻辑的本地函数 - 在本例中更新 percentValue 并设置 div.progressBar 的宽度:

function link($scope, $elem, attrs) {
    function updateProgress() {
		var percentValue = Math.round($scope.value / $scope.max * 100);
		$scope.percentValue = Math.min(Math.max(percentValue, 0), 100);
		$elem.children()[0].style.width = $scope.percentValue + '%';
	}
}

正如你所看到的,我们不能使用 .css() 来更改 div.progressBar 的宽度,因为 jqLit​​e 不支持 .children( )。我们还需要使用 Math.min()Math.max() 将值保持在 0% 到 100% 之间 - 如果 precentValue 小于 0,则 Math.max() 将返回 0;如果 percentValue 大于 100,则 Math.min() 将返回 100。

现在不再是两个 $scope.$watch() 调用(我们必须注意 $scope.value 中的变化$scope.max) 让我们使用 $scope.$watchCollection(),它类似,但适用于属性集合:

$scope.$watchCollection('[value, max]', updateProgress);

请注意,我们传递的第一个参数看起来像数组,而不是 JavaScript 的数组。

要了解它是如何工作的,首先更改 ngInit 以初始化另外两个变量:

<body ng-app="example" ng-init="textToConvert = 'This text will be converted to leet speak!'; progressValue = 20; progressMax = 100">

然后在我们之前使用的 div 下面添加 <example-progress></example-progress> 元素:

<example-progress value="progressValue" max="progressMax"></example-progress>

现在应该如下所示:

<body ng-app="example" ng-init="textToConvert = 'This text will be converted to leet speak!'; progressValue = 20; progressMax = 100"> 
    <div example-bind-leet="textToConvert"></div> 
    <example-progress value="progressValue" max="progressMax"></example-progress> 
</body> 

这就是结果:

第 4 步:使用 jQuery 添加动画

如果您为 progressValueprogressMax 添加输入,如下所示:

<input ng-model="progressValue"> 
<input ng-model="progressMax">

您会注意到,当您更改任何值时,宽度会立即发生变化。为了让它看起来更好一点,让我们使用 jQuery 来制作它的动画。将 jQuery 与 AngularJS 结合使用的好处是,当您包含 jQuery 的 <script></script> 时,Angular 会自动用它替换 jqLit​​e,使 $elem 成为 jQuery 对象。

因此,让我们首先将 jQuery 脚本添加到文档的 中,位于 AngularJS 之前:

<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>

现在我们可以更改 updateProgress() 函数以使用 jQuery 的 .animate() 方法。更改此行:

$elem.children()[0].style.width = $scope.percentValue + '%'; 

对此:

$elem.children('.progressBar').stop(true, true).animate({ width: $scope.percentValue + '%' }); 

并且您应该有一个精美的动画进度条。我们必须使用 .stop() 方法来停止并完成任何待处理的动画,以防我们在动画进行过程中更改任何值(尝试删除它并快速更改输入中的值以了解为什么需要它)。 p>

当然,您应该更改 CSS,并可能在应用程序中使用其他一些缓动函数来匹配您的风格。

结论

AngularJS 的指令对于任何 Web 开发人员来说都是一个强大的工具。您可以创建一组自己的指令来简化和促进您的开发过程。您可以创建的内容仅受您的想象力限制,您几乎可以将所有服务器端模板转换为 AngularJS 指令。

有用链接

以下是 AngularJS 文档的一些链接:

  • 开发者指南:指令
  • 综合指令 API
  • jqLit​​e(angular.element)API

Atas ialah kandungan terperinci Tingkatkan HTML dengan arahan AngularJS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn