理解角度指令
指令可以简单理解为运行在特定DOM元素上的函数,指令可以扩展这个元素的功能。
首先看一个完整的参数示例,然后详细介绍每个参数的功能和用法:
angular.module('myApp ',[])。指令(' myDirective ',function(){ return { restrict : String,priority: Number,terminal: Boolean,template: String或Template function : function(tElement,tatrs)}.},templateUrl: String,replace: Boolean或String,scope: Boolean或Object,transclude: Boolean,controller: String或function(作用域,元素,属性,transclude,other injectables){ 0.},controllerAs: String,require: String,link: function(scope,iElement,iAttrs){ 0.},Compile: //返回一个对象或连接函数,如下所示:function (telegram,ttrs,trans clude){ return { pre : function(scope,ielement,iattrs,controller)}.},post:函数(作用域、iElement、iAttrs、控制器){ 0.} }返回函数postLink(.) { .} } };});1、限制[字符串]
Restrict是可选参数。用于指定如何在DOM中声明指令。默认值为,声明为属性。可选值如下:e(元素)。
我的方向/我的方向a(属性,默认值)。
div my-指令=' expression'/div c(类名)。
div class=' my-directive : expression;'/div M(评论)
-directive : my-directive expression-一般情况下,考虑到浏览器的兼容性,强烈建议使用默认属性以属性的形式进行声明。最后一种方法建议在不再需要强制索引时不要使用它。
代码:
Angular.module ('app ',[])。指令(' mydirective ',function(){ return { restrict 3360 ' e ',template : ' a href=' http://www . Baidu.com ' Baidu/a ' };})html code : my-directional/my-directional效果:。
2、优先级[int]
大多数指令都忽略这个参数,使用默认值0,但是在某些场景中设置高优先级是非常重要的,甚至是必要的。例如,ngRepeat将此参数设置为1000,这确保了它总是在同一元素上的其他指令之前被调用。
3、终端[bool]
此参数用于在当前元素上停止运行优先级低于此指令的指令。但是,与当前指令具有相同优先级的指令仍将被执行。比如ngIf的优先级略高于ngView(他们实际控制终端参数)。如果ngIf的表达式值为真,则ngView可以正常执行,但是如果ngIf的表达式值为假,则ngView不会执行,因为它的优先级较低。
4、模板[字符串或函数]
模板参数是可选的,必须设置为以下两种形式之一:
一段HTML文本;一个接受两个参数的函数,即远程和远程,并返回一个表示模板的字符串。在远程和远程终端中,t代表模板,它是相对于实例的。首先演示第二种用法:
angular.module('app ',[])。指令(' myDirective ',function(){ return { restrict : ' EAC ',template: function (elem,attr){ return ' a href=' attr . value ' ' ' attr . text '/a ';} };})HtmlCode:(效果同上,不做演示)。
My-指令值=' http://www . Baidu.com ' text=' Baidu '/My-指令div My-指令值=' http://www . Baidu.com ' text=' Baidu '/div 5,TemplateURl[字符串或函数]。
TemplateUrl是可选参数,可以是以下类型:
表示外部HTML文件路径的字符串;一个可以接受两个参数的函数,即远程和远程,并返回一个外部HTML文件路径的字符串。无论哪种方式,模板的URL都将通过ng的内置安全层,尤其是$getTrustedResourceUrl,它可以保护模板免受不可信来源的加载。默认情况下,当调用指令时,Ajax会在后台请求HTML模板文件。加载大量模板会严重降低客户端应用程序的速度。为了避免延迟,您可以在部署应用程序之前缓存HTML模板。
代码:
angular.module('app ',[])。指令(' myDirective ',function(){ return { restrict : ' AEC ',template URLs : function(elem,attr){ return attr . value }。html ';//当然,这里我们可以直接指定路径,同时可以在模板中包含表达式} };})6、替换[bool]
替换是可选参数。如果设置了此参数,该值必须为真,因为默认值为假。默认值意味着模板将作为子元素插入到调用此指令的元素中。例如,在上面示例中的默认值的情况下,生成的html代码如下:
My-directive值=' http://www . Baidu.com ' text=' Baidu ' a href=' http://www . Baidu.com ' Baidu/a/my-directive if replace=true设置。
a href=' http://www . Baidu.com ' value=' http://www . Baidu.com ' text=' Baidu ' Baidu/a据我观察,这种效果只有设置了restrict='E '才会显示出实际效果。
在介绍了基本的指令参数之后,将涉及更重要的作用域参数。
7.范围参数[bool或object]。
范围参数是可选的,可以设置为true或对象。默认值为假。
如果一个元素上的多个指令使用隔离范围,则只有其中一个指令可以生效。只有指令模板中的根元素才能获得新的作用域。因此,默认情况下,这些对象的范围设置为true。内置指令ng-controller的功能是从父作用域继承并创建一个新的子作用域。它创建一个从父作用域继承的新的子作用域。在这里,我们不需要重复继承,这与面向对象中的继承基本一致。
让我们首先分析一段代码:
Div-app=' app' ng-init=' name='祖父'' div ng-init='name='父亲' '第一代:{{ name } } div ng-init=' name=' son ' ' ng-controller=' some controller '第二代:{ { name。Div-init=' name='孙子''第三代:{{ name }} /div /div /div /div我们发现第一代,我们把名字初始化为父代,但是第二代和第三代实际上是一个作用域,所以他们的名字实际上是一个对象,所以效果如下:
第一代:父亲的第二代:孙子的第三代:孙子,我们在修改代码,隔离第三代,看效果;
Div-app=' app' ng-init=' name='祖父'' div ng-init='name='父亲' '第一代:{{ name } } div ng-init=' name=' son ' ' ng-controller=' some controller '第二代:{ { name。Div-init=' name='孙子' ' ng-controller='第二代controller '第三代:{ { name } }/div/div/div jscode :
棱角分明。模块(' app ',[])。控制器('某些控制器',函数($ scope) {})。控制器('第二个控制器',函数($ scope) {})具有以下效果:
第1代:父亲第2代:儿子第3代:孙子正在修改代码查看继承;
Div-app=' app' ng-init=' name='祖父之吻' ' Div第一代:{{name}} div ng-controller='某些控制器'第二代:{{name}} div ng-controller='第二代控制器'第三代:{{name}}/div/。
第一代:祖父之吻第二代:祖父之吻第三代:祖父之吻如果要创建一个可以从外部原型继承作用域的指令,将作用域属性设置为true只是可继承的隔离,即不能反向影响父作用域。
我们再举一个例子:
angular.module('myApp ',[])。控制器(' MainController ',函数($scope) { })。指令(' myDirective ',function(){ return { restrict : ' A ',Scope:false,//switch to {},true test priority : 100,template :' div内部: { { my property } } input ng-model=' my property '/div ' };});Html代码:
div ng-controller=' main controller ' ng-init=' my property=' Hello World!external : { { my property } } Input ng-model=' my property '/div my-directional/div/div当我们更改范围的值时,我们会发现。
True :继承但不隔离。
True:继承和隔离。
{}:孤立且未继承。
8、跨集群
Clude是一个可选参数。默认值为假。嵌入通常用于创建可重用的组件。典型的例子是模态对话框或导航栏。我们可以将整个模板,包括其中的指令,嵌入到一个指令中。外部指令的作用域可以由指令内部访问,模板也可以访问外部作用域对象。为了传递作用域,作用域参数的值必须通过{}或true设置为隔离作用域。如果未设置作用域参数,指令内部的作用域将被设置为传入模板的作用域。
仅当您想要创建可以包含任何内容的指令时,才使用transclude: true。
让我们看两个例子——导航栏:
div侧框标题=' TagCloud ' div class=' TagCloud ' a href=' Graphics/a href=' ng/a href=' D3/a href='前端/a href=' '启动/a /div /divJsCode:
angular.module('myApp ',[])。指令(' sideBox ',函数(){ return { restrict: 'EA ',scope: { title: '@' },transclude: true,template : ' div class=' sideBox ' div class=' content ' H2 class=' header ' ' { { title } }/H2 span class=' content ' ng-transclude/span/div/div ' };});这段代码告诉ng编译器将从DOM元素中获得的内容放在找到ng-transclude指令的地方。
这里还有一个官网的例子:
angular . module(' DocSisofBindExample ',[])。控制器(' controller ',['$scope ',' $timeout ',函数($scope,$ time out){ $ scope . name=' Tobias ';$ scope . hidedialog=function(){ $ scope . dialogishidden=true;$ time out(function(){ $ scope . dialogishidden=false;}, 2000);};}]) .指令(' myDialog ',函数(){ return { restrict: 'E ',transclude: true,scope : { ' close ' : ' onClose ' },template URLs : ' my-dialog-close . html ' };});my-dialog-close.html
div class=' alert ' a href class=' close ' ng-click=' close()'/a div ng-trans clude/div/divindex . html
div ng-Controller=' Controller ' my-dialog ng-hide=' dialogIsHidden ' on-close=' hide dialog()'查看内容,{{name}}!/my-dialog/div如果指令使用transclude参数,则控制器无法正常监控数据模型的变化。建议在链接功能中使用$watch服务。
9、控制器[字符串或函数]
控制器参数可以是字符串或函数。当设置为字符串时,将使用字符串的值作为名称来搜索在应用程序中注册的控制器的构造函数。
棱角分明。模块(' myapp ',[])。指令(' mydirective ',function () {restrict3360' a ',controller : ' some controller ' })可以通过指令内的匿名构造函数定义内联控制器。
Angular.module ('myapp ',[])。指令(' mydirective ',function () {restrict3360' a ',controller: function ($ scope,$ element,$ attrs,$ trans clude){//控制器逻辑在这里} });我们可以注入任何可以注入控制器的ng服务,然后我们可以在指令中使用它。控制器中还有一些特殊服务可以注入到指令中。这些服务是:
1.$范围
与指令元素关联的当前范围。2.$元素对应于当前指令的元素。3.$attrs由当前元素的属性组成的对象。
Div id='aDiv'class='box'/div具有以下属性对象:{id:' adiv ',class:' box'} 4。$ transclude嵌入链接函数将与相应的嵌入范围预绑定。Transclude链接函数是一个实际执行来克隆元素和操作DOM的函数。
angular.module('myApp ',[])。指令(' myLink ',function(){ return { restrict : ' EA ',transclude: true,controller: function ($scope,$element,$attrs,$ trans clude){ $ trans clude(function(clone){ var a=angular . element(' a ');a.attr('href ',$ attrs . value);a . text(clone . text());$ element . append(a);});} };});超文本标记语言
My-link value=' http://www . Baidu.com ' Baidu/My-link div My-link value=' http://www . Google.com ' Google/div建议只在编译参数中使用transcludeFn。链接功能可以将指令相互隔离,而控制器定义可重用的行为。如果我们想将当前指令的API公开给其他指令,可以使用controller参数,否则可以使用link构造当前指令元素的功能(即内部函数)。如果我们使用范围。$watch()或者想要与DOM元素实时交互,使用链接是更好的选择。使用嵌入,控制器中范围反映的范围可能与我们预期的不同。在这种情况下,不能保证$scope对象正常更新。当您想要与当前屏幕上的范围进行交互时,可以使用传递到链接函数中的范围参数。
10、controller as[字符串]
controllerAs参数用于设置控制器的别名,这样就可以在视图中引用控制器,甚至不需要注入$scope。
div ng-controller=' main controller as main '输入类型=' text ' ng-model=' main . name '/span { { main . name } }/span/div jscode :
angular.module('myApp ',[])。控制器(' MainController ',function(){ this . name=' Halower ';});控制器的别名使得路由和指令具有强大的创建匿名控制器的能力。这种能力可以创建一个动态对象作为控制器,并且这个对象是隔离的,易于测试。
11、要求[字符串或字符串[]]
Require是表示另一个指令名称的字符串。Require将控制器注入到它指定的指令中,并将其作为当前指令的链接函数的第四个参数。字符串或数组元素的值是将在当前指令范围内使用的指令名称。在任何情况下,ng编译器在搜索子控制器时都会参考当前指令的模板。
如果不使用前缀,指令将只在自己的元素上寻找控制器。指令定义将只找到在当前使用该指令的域中定义的ng-model=' '。如果使用?前缀,如果在当前指令中没有找到所需的控制器,则null将作为传递给link函数的第四个参数。如果添加前缀,指令将在上游指令链中寻找由require参数指定的控制器。如果加上?结合前面两个选项的行为,我们可以选择加载所需的指令,并在父指令链中查找它。如果没有前缀,指令将在自己提供的控制器中查找。如果找不到控制器(或具有指定名称的指令),将引发错误。12.编译【对象或函数】。
编译选项本身并不经常使用,但是链接函数经常使用。本质上,当我们设置链接选项时,我们实际上创建了一个postLink()链接函数,这样compile()函数就可以定义链接函数。一般如果设置了编译函数,就意味着我们要在指令和实时数据放入DOM之前执行DOM操作。在这个函数中执行添加和删除节点等DOM操作是安全的。
编译和链接选项是互斥的。如果两个选项同时设置,编译返回的函数将被视为链接函数,链接选项本身将被忽略。
编译器功能负责转换模板DOM。链接函数负责链接范围和DOM。您可以在将作用域链接到DOM之前手动操作它。实际上,这种操作在编写自定义指令时非常少见,但有几个内置指令提供了这样的功能。
13、链接
编译:函数(tele,t attrs,transcludefn) {//todo :返回函数(scope,ele,attrs){//link function };链接功能是可选的。如果定义了一个编译函数,它将返回链接函数,所以当两个函数都被定义时,编译函数将重载链接函数。如果我们的指令很简单,不需要额外的设置,我们可以从工厂函数(回调函数)返回一个函数,而不是对象。如果这样做了,这个函数就是链接函数。
14、模型
它提供了一个较低级别的应用编程接口来处理控制器中的数据。这个API是用来处理数据绑定、验证、CSS更新等实际不操作DOM的事情。ngModel控制器将与包含一些方法的ngModel一起被注入到指令中。必须使用必需设置才能访问网络模型控制器。
ngModelController的常见元素如下:
1).为了在范围内设置视图值,需要调用ngModel。$setViewValue()函数。$setViewValue()方法适合在自定义指令中监听自定义事件(例如,使用带有回调函数的jQuery插件),我们希望在回调过程中设置$viewValue并执行摘要循环。
angular.module('myApp ')。指令(' myDirective ',function(){ return { require : }?' n model ',link:函数(范围、元素、属性、n model){ if(!ngModel)返回;$ (function () {ele。date picker({//回调函数onSelect:函数(date) {//设置视图并调用applyscope。$ apply(function(){ n model。$ setview value(date));});} });});} };});2).$render方法可以定义视图的特定呈现模式3)。属性(这里,属性可以通过参考上一篇文章的结尾来学习)。
以上都是关于AngularJs的指导,希望对大家的学习有所帮助。