AngularJS の主な機能は、HTML の機能を拡張して、今日の動的 Web ページの目的を達成できることです。この記事では、AngularJS のディレクティブを使用して開発を迅速かつ簡単にし、コードをより保守しやすくする方法を説明します。
######準備する######ファイルをドキュメントの
に追加します。
リーリー
ステップ 2: モジュールの作成
:
の下部にある script タグに記述します。 リーリー 依存関係がないため、angular.module() の 2 番目のパラメーターの配列は空ですが、完全に削除しないと、$injector:nomod エラーが発生します。なぜなら
angular.module()
アプリケーションが正しく動作するには、
ng-app="example" 属性を
タグに追加する必要もあります。ファイルは次のようになります:
リーリー
属性コマンド: 1337 C0NV3R73R
module.directive()
2 番目のパラメータとして渡される関数は、命令を説明するオブジェクトを返す必要があります。現在、属性は 1 つだけです: link function:
リーリー
関数は、return ステートメントの前、または返されたオブジェクト内で直接定義できます。これは、ディレクティブが適用される要素の DOM を操作するために使用され、3 つの引数で呼び出されます:
リーリーはこのディレクティブと一致する DOM 要素です (AngularJS のサブセットである jqLite e でラップされています)
attrs は、すべての要素属性を持つオブジェクトです (正規化された名前を持つため、example-bind-leet は attrs.exampleBindLeet
として使用できます)。
ディレクティブ内のこの関数の最も単純なコードは次のようになります:
リーリー
まず、example-bind-leet
属性で指定されたテキスト内の一部の文字を、leet テーブルの置換コンテンツに置き換えます。テーブルは次のようになります:
これを
タグの先頭に置く必要があります。ご覧のとおり、これは 10 文字のみを置換するため、最も基本的な leet コンバータです。
text() メソッドを使用して、このディレクティブに一致する要素の内部テキストに挿入します。 <script>
</script>
この HTML コードをドキュメントの
に配置してテストできます:
リーリー
しかし、それは ngBind
ディレクティブの正確な仕組みではありません。次のステップでこれを変更します。
まず第一に、
このオブジェクトのすべてのプロパティは、ディレクティブのスコープ内で使用できます。その値はここの値によって決まります。 「-」を使用すると、値は同じ名前のプロパティの値と等しくなります。 "= を使用すると、現在のスコープで変数を渡すことを期待していることがコンパイラーに伝えられます。これは、ngBind
:
プロパティ名として任意のものを使用し、正規化された (キャメルケースに変換された) プロパティ名を - または = の後に置くこともできます。
リーリーあなたに最も適したものを選択してください。ここで、attr
の代わりに
を使用するようにリンク関数を変更する必要もあります:
function link($scope, $elem, attrs) { var leetText = $scope.exampleBindLeet.replace(/[abegilostz]/gmi, function (letter) { return leet[letter.toLowerCase()]; }); $elem.text(leetText); }
现在使用 ngInit 或创建一个控制器,并将 div
的 example-bind-leet
属性的值更改为您使用的变量的名称:
<body ng-app="example" ng-init="textToConvert = 'This text will be converted to leet speak!'"> <div example-bind-leet="textToConvert"></div> </body>
但这仍然不是 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>
。
为了让我们的进度条看起来像一个进度条,我们必须使用一些 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:relative
和 position:absolute
的组合来定位绿色条和 <example-progress>
元素。
与前一个相比,这个需要更多的选项。看一下这段代码(并将其插入到您的 <script>
标记中):
module.directive('exampleProgress', function () { return { restrict: 'E', scope: { value: '=', max: '=' }, template: '', link: link }; });
正如您所看到的,我们仍然使用范围(这次有两个属性 - value 表示当前值,max 表示最大值)和 link() 函数,但有两个新属性:
当然,我们不会将模板留空。将此 HTML 放在那里:
<div class="progressBar"></div><div class="progressValue">{{ percentValue }}%</div>
如您所见,我们还可以在模板中使用 Angluar 表达式 - percentValue
将从指令的范围中获取。
该函数与上一个指令中的函数类似。首先,创建一个将执行指令逻辑的本地函数 - 在本例中更新 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 的宽度,因为 jqLite 不支持 .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>
这就是结果:
如果您为 progressValue
和 progressMax
添加输入,如下所示:
<input ng-model="progressValue"> <input ng-model="progressMax">
您会注意到,当您更改任何值时,宽度会立即发生变化。为了让它看起来更好一点,让我们使用 jQuery 来制作它的动画。将 jQuery 与 AngularJS 结合使用的好处是,当您包含 jQuery 的 <script>
时,Angular 会自动用它替换 jqLite,使 $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 文档的一些链接:
以上がAngularJS ディレクティブを使用して HTML を強化するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。