### [使用 AngularJS 指令增强 HTML](https://www.prosaas.cn/article/7166) **Published:** 2023-08-27T00:01:15 **Author:** 5201314 **Excerpt:** AngularJS 的主要特点是它允许我们扩展 HTML 的功能来服务于当今动态网页的目的。在本文中,我将向您… ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804881.jpg) AngularJS 的主要特点是它允许我们扩展 HTML 的功能来服务于当今动态网页的目的。在本文中,我将向您展示如何使用 AngularJS 的指令来使您的开发更快、更轻松,并且使您的代码更易于维护。 ## **准备** ### **第 1 步:HTML 模板** 为了让事情变得更简单,我们将把所有代码编写在一个 HTML 文件中。创建它并将基本的 HTML 模板放入其中: 现在将来自 Google CDN 的 `angular.min.js` 文件添加到文档的 中: ### **第 2 步:创建模块** 现在让我们为指令创建模块。我将其称为 _example_,但您可以选择任何您想要的名称,只需记住我们将使用此名称作为稍后创建的指令的命名空间。 将此代码放在 底部的脚本标记中: var module = angular.module('example', \[\]); 我们没有任何依赖项,因此 `angular.module()` 的第二个参数中的数组为空,但不要完全删除它,否则您将得到 $injector:nomod错误,因为 `angular.module()` 的单参数形式检索对已存在模块的引用,而不是创建新模块。 您还必须将 `ng-app="example"` 属性添加到 标记才能使应用程序正常工作。之后文件应如下所示: ## **属性指令: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' }; 您应该将其放在 标记的顶部。正如您所看到的,这是最基本的 leet 转换器,因为它仅替换十个字符。 之后,我们将字符串转换为 leet say,我们使用 jqLit​​e 的 `text()` 方法将其放入该指令匹配的元素的内部文本中。 现在您可以通过将此 HTML 代码放入文档的 中来测试它:
输出应如下所示: 但这并不完全是 `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); } 现在使用 ngInit 或创建一个控制器,并将 `div` 的 `example-bind-leet` 属性的值更改为您使用的变量的名称:
### **第 4 步:检测更改** 但这仍然不是 `ngBind` 的工作原理。要查看我们添加一个输入字段以在页面加载后更改 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` 的内容也按预期发生了变化。 ## **元素指令:进度条** 现在我们将编写一个指令来为我们创建一个进度条。为此,我们将使用一个新元素:。 ### **第 1 步:样式** 为了让我们的进度条看起来像一个进度条,我们必须使用一些 CSS。将此代码放入文档的 中的 元素中: 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` 的组合来定位绿色条和 元素。 ### **第 2 步:指令的属性** 与前一个相比,这个需要更多的选项。看一下这段代码(并将其插入到您的 标记中): 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 放在那里:
{{ percentValue }}%
如您所见,我们还可以在模板中使用 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` 以初始化另外两个变量: 然后在我们之前使用的 `div` 下面添加 元素: 现在应该如下所示:
这就是结果: ### **第 4 步:使用 jQuery 添加动画** 如果您为 `progressValue` 和 `progressMax` 添加输入,如下所示: 您会注意到,当您更改任何值时,宽度会立即发生变化。为了让它看起来更好一点,让我们使用 jQuery 来制作它的动画。将 jQuery 与 AngularJS 结合使用的好处是,当您包含 jQuery 的 时,Angular 会自动用它替换 jqLit​​e,使 `$elem` 成为 jQuery 对象。 因此,让我们首先将 jQuery 脚本添加到文档的 中,位于 AngularJS 之前: 现在我们可以更改 `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的详细内容,更多请关注知企PROSAAS其它相关文章! ![](/static/logo.png) 智能AI问答 PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。 我要提问 相关标签: jquery css html angular 命名空间 回调函数 字符串 JS 对象 作用域 dom position 来源:知企PROSAAS ![](images/2023/1212/shoucang_2x.png) 收藏 ![](images/2023/1212/icon37.png) 点赞 上一篇:Vanilla JavaScript:从日期中添加或减去天数(以及更多) 下一篇:Telerik:从角度专业知识到移动精通 ![](images/2023/1212/benzhanshengming.png) 本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn 作者最新文章 - 海南计划对电动汽车实施不同的峰谷分时电价政策,以区分迎峰度夏和非迎峰度夏两个阶段 2023-12-06 09:05:09 - AI人才市场掀起大模型热潮,薪资涨幅高达26.85% 2023-12-06 08:57:38 - 深圳:到 2025 年使通用算力达到 14EFLOPS,智能算力达 25EFLOPS,超算算力达 2EFLOPS 2023-12-06 08:57:33 - 美图推出AI模型MiracleVision 4.0版 支持文生视频 2023-12-06 08:51:41 - Copilot 下一步计划,将支持 GPT-4 Turbo 和新的 DALL-E 3 模型 2023-12-06 08:29:54 - 在iPhone上查看已保存的密码的方法 2023-12-06 08:13:27 - 微软公布 Copilot 下一步计划,将支持 GPT-4 Turbo 和新的 DALL-E 3 模型 2023-12-06 08:03:27 - 尾号“999999”天价手机号流拍后续:孕妇恶意竞拍,罚款 8 万元 2023-12-05 21:57:51 - 今晚国内油价迎“五连降”,加满一箱 92 号汽油少花 2 元 2023-12-05 21:50:04 - 2023 操作系统产业大会暨统信 UOS 生态大会定档 12 月 20 日 2023-12-05 21:43:40 最新问题 Laravel Cashier - Stripe 多种付款方式 我的餐厅使用LaravelCashier和Stripe。我想为我的客户使用Stripe支持的多种付款方式,但我在LaravelCashier文档中找不到有关在Stripe中使用多种... P粉652495194来自于2023-12-11 18:56:12 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)2 ![](images/2023/1212/icon43.png)214 FastAPI: 如何在HTML文件中同时渲染CSS/JS/Images? 我在FastAPI中渲染HTMl文件时遇到问题。ma​​in.py文件static\_dir=os.path.join(os.path.dirname(\_\_file\_\_),"... P粉237125700来自于2023-12-11 17:58:49 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)1 ![](images/2023/1212/icon43.png)240 老师,笔记能分享一下吗 老师,笔记能分享一下吗 手机用户3055476来自于2023-12-12 16:46:38 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)0 ![](images/2023/1212/icon43.png)25 Nuxt 构建错误:TypeError:无法解构属性“nuxt”的“这个”因为它是未定义的 我想创建一个新的Nuxt项目并按照此处的说明进行操作:https://nuxtjs.org/docs/get-started/installation。基本上只是运行npminit... P粉156415696来自于2023-12-11 16:47:40 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)2 ![](images/2023/1212/icon43.png)169 CSS径向渐变到SVG径向渐变 是否可以在SVG中制作径向渐变,就像在CSS中一样http://codepen.io/A973C/pen/hnEaf(我指的是交通灯中的灯).red{background:red;... P粉308783585来自于2023-12-11 15:54:09 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)2 ![](images/2023/1212/icon43.png)243 未定义类型“Validator”.intelephense(1009) 谁能帮我解决这个错误吗?我是Laravel新手,我正在制作一个ProductController文件,但我从Validator收到此错误:我已经调用了useValidator;我还... P粉010967136来自于2023-12-11 15:05:11 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)1 ![](images/2023/1212/icon43.png)197 Laravel 9 上未找到混合清单 - vite 当我运行npmrunbuild时遇到问题,它说找不到混合清单。当我在生产中运行时会发生这种情况。我的npm-v是9.1.2并运行laravel9,带有“php”:“^8.0.2”。... P粉974462439来自于2023-12-11 13:40:48 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)1 ![](images/2023/1212/icon43.png)218 Vue3:如何将参数发送到路由而不将它们添加到 Vue3 中的 url 中? 在Vue3中,有没有一种方法可以将属性传递给路由,而无需在url中显示值?我这样定义路线:{path:'/someRoute',name:'someRoute',component... P粉465675962来自于2023-12-11 13:07:20 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)1 ![](images/2023/1212/icon43.png)214 在JSP bean中实现动态文本框及其值的提交 我有一个带有几个预定义文本框的表单,现在除此之外我还创建了一些动态文本框,我可以用javascript来完成它(我猜)。提交表单时,如何将动态生成的文本框的值设置为bean。在be... P粉916760429来自于2023-12-11 11:56:28 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)1 ![](images/2023/1212/icon43.png)190 识别特定行具有一致值的列名 我正在尝试在mysql中进行查询以获取某一特定行具有特定值的任何列。在Mysql中,我们可以根据列的任何特定值获取行。我有一个像这样的表:+----+------------+--... P粉738046172来自于2023-12-11 09:56:34 ![](images/2023/1212/icon37.png)0 ![](images/2023/1212/icon24.png)1 ![](images/2023/1212/icon43.png)133 相关专题 更多> - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804926.png) jquery插件有哪些 - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804778.png) jquery怎么操作json - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804112.png) jquery删除元素的方法 - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804233.png) jQuery hover()方法的使用 - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804621.png) jquery实现分页方法 - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804224.png) css - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125804256.png) css居中 - ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125805999.png) css如何插入图片 **Tags:** angular, css, dom, html, jquery, JS, position, 作用域, 命名空间, 回调函数 **Categories:** WordPress ---