AngularJS ディレクティブを使用して HTML を強化する

王林
リリース: 2023-08-27 08:01:15
オリジナル
711 人が閲覧しました

使用 AngularJS 指令增强 HTML

AngularJS の主な機能は、HTML の機能を拡張して、今日の動的 Web ページの目的を達成できることです。この記事では、AngularJS のディレクティブを使用して開発を迅速かつ簡単にし、コードをより保守しやすくする方法を説明します。

######準備する######

ステップ 1: HTML テンプレート

作業を簡単にするために、すべてのコードを 1 つの HTML ファイルに記述します。これを作成し、基本的な HTML テンプレートをそこに置きます: リーリー 次に、Google CDN から

angular.min.js

ファイルをドキュメントの

に追加します。 リーリー ステップ 2: モジュールの作成

次に、ディレクティブのモジュールを作成しましょう。これを

example という名前にしますが、任意の名前を選択できます。この名前は、後で作成するディレクティブの名前空間として使用することに注意してください。

このコードを

:

の下部にある script タグに記述します。 リーリー

依存関係がないため、angular.module() の 2 番目のパラメーターの配列は空ですが、完全に削除しないと、$injector:nomod エラーが発生します。なぜなら angular.module()

の単一引数形式は、新しいモジュールを作成するのではなく、既存のモジュールへの参照を取得します。

アプリケーションが正しく動作するには、ng-app="example" 属性を

タグに追加する必要もあります。ファイルは次のようになります: リーリー 属性コマンド: 1337 C0NV3R73R

まず、ngBind と同様に機能する単純なディレクティブを作成しますが、テキストが leet talk に変更されます。

ステップ 1: 指示文

module.directive()

メソッドを使用して命令を宣言します: リーリー 最初のパラメータは命令の名前です。キャメルケースである必要がありますが、HTML では大文字と小文字が区別されないため、HTML コードではダッシュ区切りの小文字 (example-bind-leet) を使用します。

2 番目のパラメータとして渡される関数は、命令を説明するオブジェクトを返す必要があります。現在、属性は 1 つだけです: link function: リーリー

ステップ 2: リンク機能

関数は、return ステートメントの前、または返されたオブジェクト内で直接定義できます。これは、ディレクティブが適用される要素の DOM を操作するために使用され、3 つの引数で呼び出されます:

リーリー

$scope は Angular スコープ オブジェクト、

$elem

はこのディレクティブと一致する DOM 要素です (AngularJS のサブセットである jqLit​​e e でラップされています)

attrs

は、すべての要素属性を持つオブジェクトです (正規化された名前を持つため、example-bind-leet は attrs.exampleBindLeet として使用できます)。 ディレクティブ内のこの関数の最も単純なコードは次のようになります: リーリー まず、example-bind-leet 属性で指定されたテキスト内の一部の文字を、leet テーブルの置換コンテンツに置き換えます。テーブルは次のようになります:

リーリー

これを

タグの先頭に置く必要があります。ご覧のとおり、これは 10 文字のみを置換するため、最も基本的な leet コンバータです。

その後、文字列を leet に変換します。これを jqLit​​e の

text() メソッドを使用して、このディレクティブに一致する要素の内部テキストに挿入します。 <script> </script>この HTML コードをドキュメントの

に配置してテストできます: リーリー

出力は次のようになります:

しかし、それは ngBind ディレクティブの正確な仕組みではありません。次のステップでこれを変更します。

ステップ 3: 範囲

まず第一に、

example-bind-leet

属性で渡されるものは、変換するテキストではなく、現在のスコープ内の変数への参照である必要があります。これを行うには、ディレクティブの分離スコープを作成する必要があります。 これは、ディレクティブ関数の戻り値にスコープ オブジェクトを追加することで実現できます。

リーリー

このオブジェクトのすべてのプロパティは、ディレクティブのスコープ内で使用できます。その値はここの値によって決まります。 「-」を使用すると、値は同じ名前のプロパティの値と等しくなります。 "= を使用すると、現在のスコープで変数を渡すことを期待していることがコンパイラーに伝えられます。これは、ngBind:

のように機能します。 リーリー

プロパティ名として任意のものを使用し、正規化された (キャメルケースに変換された) プロパティ名を - または = の後に置くこともできます。

リーリー

あなたに最も適したものを選択してください。ここで、attr の代わりに

$scope

を使用するようにリンク関数を変更する必要もあります:

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>

第 1 步:样式

为了让我们的进度条看起来像一个进度条,我们必须使用一些 CSS。将此代码放入文档的 <head> 中的 <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> 元素。

第 2 步:指令的属性

与前一个相比,这个需要更多的选项。看一下这段代码(并将其插入到您的 <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 value="progressValue" max="progressMax"></example-progress>
ログイン後にコピー

<body> 现在应该如下所示:

<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> 时,Angular 会自动用它替换 jqLit​​e,使 $elem 成为 jQuery 对象。

因此,让我们首先将 jQuery 脚本添加到文档的 <head> 中,位于 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

以上がAngularJS ディレクティブを使用して HTML を強化するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート