全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

AngularJS动态菜单操作指令

前言    

    在我们创建一个angularJS应用的时候,菜单往往往是不可或缺的元素之一。也许在我们静态菜单的时候不会发现在指令中操作菜单收缩、折叠展开没有任何问题,因为我们在操作之前,页面元素渲染已经完成,所以在指令里面通过element查找目标元素可以成功。但是一旦我们的菜单的数据不是静态而是通过后台接口加载动态数据渲染,我们会发现本来在静态写好的指令操作,在转变为动态数据加载之后,怎么也没法查找到想要的目标元素。

    遇到如此问题,开始觉得好奇葩的,当然这也是吐槽一下,还是得好好解决问题的,痛定失痛,决心好好理清思路,分析一下问题原因。首先我们先了解一下AngularJS的生命周期。

AngularJS的生命周期

    在AngularJS应用启动前,它们会以HTML文本的形式保存在文本编辑器中。应用启动后会进行编译和链接,作用域会同HTML进行绑定,应用可以对用户在HTML中进行的操作进行实时响应。AngularJS的生命周期主要有两个主要阶段:一个是编译阶段,一个是链接阶段。

AngularJS生命周期-编译阶段

    在编译阶段,AngularJS会遍历整个HTML文档并根据JavaScript中的指令定义来处理页面上声明的指令。每一个指令模板中可能有另一个指令,另一个指令也有可能会有自己的模板。AngularJS调用HTML文档根部的指令时,会遍历其中所有的模板,模板中可能含有模板的指令。如果一个元素已经有一个含有模板的指令,永远不要对其用另一个指令进行修饰,只有最高优先级的指令中的模板会被编译。

    一旦对指令和其中的子模板进行遍历或编译,编译后的模板会返回一个叫做模板函数的函数。在这个时候的DOM树还没有进行数据绑定,此时对DOM树操作只会有很少的性能开销,ng-repeat和ng-transclude等内置指令会在这个时候对还未进行数据绑定的DOM进行操作。比如ng-repeat,它会遍历指定的数组或对象,在数据绑定之前构建对应的DOM结构,然后将新的DOM(编译后的DOM)传递给指令生命周期中的下一阶段,链接阶段。一个指令的DOM一旦编译完成,就可以立即通过编译函数对其进行访问,编译函数的签名包含有访问指令声明所在的元素(tElements)及该元素对其他属性(tAttrs)的方法。

    compile返回对象或函数,compile()函数负责对模板DOM进行转换,link()函数负责将作用域和DOM进行转换。

//...
compile: function(tEle,tAttrs,transcludeFn){
 var tplEl = angular.element('<div>' +'<h2></h2>'+'</div>');
 var h2 = tplEl.find('h2');
 h2.attr('type',tAttrs.type);
 h2.attr('ng-model',tAttrs.ngModel);
 h2.val('hello');
 tEle.replaceWith(tplEl);
 return function(scope, ele, attrs){
  //连接函数
 };
}
//...

 AngularJS生命周期-链接阶段

    link函数创建可以操作DOM的指令,链接函数是可选的。定义了编译函数,返回链接函数,当两个函数都定义了,编译函数会重载链接函数。

//下面2种定义指令的放松在功能上是完全一样的
angular.module('myApp',[])
.directive('myDirective', function (){
 return {
 pre: function (tElement, tAttrs, transclude){
 //在子元素被链接之前执行,之后调用‘link'函数无法定位链接的元素
 
 },
 post: function (scope, iElement, iAttrs, controllers){
   //在子元素被链接之后执行
 }
 }
});
angular.module('myApp',[])
.directive('myDirective', function (){
 return {
 link: function (scope, ele, attrs){
  return {
  pre: function (tElement, tAttrs, transclude){
  //在子元素被链接之前执行,之后调用‘link'函数无法定位链接的元素
  },
  post: function (scope, iElement, iAttrs, controllers){
    //在子元素被链接之后执行
  }
  }
 }
 }
});

    当定义了编译函数来取代链接函数时,链接函数使我们能提供给返回对象的第二个方法,也就是postLink函数。链接函数会在模板编译并同作用域进行链接后被调用。

//链接函数签名
link: function(scope, element, attrs){
 //操作DOM
}
//含require选项, require someContainer
link: function(scope, element, attrs, someContainer){
 //在这里操作DOM,可以访问require指定的控制器
}
  • scope--指令用来在其内部的作用域;
  • element--参数代表实例元素,指使用此指令的元素;
  • atrrs--代表实例属性,是一个由定义在元素上的属性组成的标准化列表,可以在所有指令的链接函数间共享,会以javascript对象的形式进行传递;
  • controller 参数指向require选项定义的控制器。没有设置require选项,controller的参数为undefined;

    控制器在所有的指令间共享,因此指令可以将控制器当作通信通道(公共API),如果设置多个require,这个参数是一个控制器实例组成的数组,而不是一个单独的控制器。

问题剖析

    在通过对AngularJS生命周期的理解,我们可以清晰地认识到动态菜单为什么绑定在链接阶段上的DOM操作没有成功,由于ng-repeat的原因,我对DOM树操作没找到DOM元素。因为在封装成一个菜单指令组件的时候,我内部的菜单数据加载使用ng-repeat实现,所以只有在这个时候才能在ng-repeat内部绑定对DOM树的操作。

    最初的写法:

//html 
<menu-bar>
`````
<div ng-repeat="ml in menuLists">
 ``````
 <div ng-repeat="mls in ml.secondLists">
 ``````
 <div ng-repeat="mlt in mls.thirdLists">
 ``````
 </div>
 ``````
 </div>
 ``````
</div>
``````
</menu-bar>
//directive
angular.module('',[]).directive('menuBar',function (){
 return {
 restrict: 'E',
 replace: true,
 link: function (scope, element, attr){
 //操作菜单的逻辑代码
 }
 }
});

    这种写法,在link里面操作菜单逻辑的代码没有被触发,angularjs的检测机制也没用,因为ng-repeat的原因导致DOM操作事件没有被挂载到DOM上,所以想操作菜单不可能成功。但是,如果ng-repeat的内容是静态存在的,link函数里面的操作是可以实现的。

    修改后的写法:

//html 
<div ng-repeat="ml in menuLists">
 ``````
 <div ng-repeat="mls in ml.secondLists">
 ``````
 <menu-bar>
 ``````
 <div ng-repeat="mlt in mls.thirdLists">
 ``````
 <menu-bar>
  ``````
 </menu-bar>
 ``````
 </div>
 ``````
 </menu-bar>
 ``````
 </div>
 ``````
</div>
//directive
angular.module('',[]).directive('menuBar',function (){
 return {
 restrict: 'E',
 replace: true,
 link: function (scope, element, attr){
 //操作菜单的逻辑代码
 }
 }
});

    修改之后我们将我们操作动态加载的DOM结构的指令放入ng-repeat中,此时逻辑正常执行,在link函数中能打印出DOM结构。

以上所述是小编给大家介绍的AngularJS动态菜单操作指令,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# angularjs 动态菜单  # angularjs操作指令  # 绑定  # 遍历  # 是一个  # 加载  # 会有  # 在这个  # 会在  # 对其  # 会以  # 小编  # 自己的  # 文档  # 在这里  # 还没有  # 也有  # 不可能  # 多个  # 在此  # 没有任何  # 我对 


相关文章: 重庆市网站制作公司,重庆招聘网站哪个好?  网站建设设计制作营销公司南阳,如何策划设计和建设网站?  建站之星后台管理:高效配置与模板优化提升用户体验  建站之星安装后如何配置SEO及设计样式?  湖州网站制作公司有哪些,浙江中蓝新能源公司官网?  如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  黑客如何利用漏洞与弱口令入侵网站服务器?  如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?  网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?  如何通过网站建站时间优化SEO与用户体验?  c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】  已有域名建站全流程解析:网站搭建步骤与建站工具选择  Bpmn 2.0的XML文件怎么画流程图  ,网站推广常用方法?  已有域名如何免费搭建网站?  建站主机空间推荐 高性价比配置与快速部署方案解析  建设网站制作价格,怎样建立自己的公司网站?  如何在云服务器上快速搭建个人网站?  如何快速生成高效建站系统源代码?  视频网站app制作软件,有什么好的视频聊天网站或者软件?  如何构建满足综合性能需求的优质建站方案?  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  高防服务器租用如何选择配置与防御等级?  小型网站制作HTML,*游戏网站怎么搭建?  山东网站制作公司有哪些,山东大源集团官网?  建站之星安装提示数据库无法连接如何解决?  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  如何快速搭建虚拟主机网站?新手必看指南  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  如何在搬瓦工VPS快速搭建网站?  网站制作报价单模板图片,小松挖机官方网站报价?  枣阳网站制作,阳新火车站打的到仙岛湖多少钱?  建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析  电脑免费海报制作网站推荐,招聘海报哪个网站多?  潍坊网站制作公司有哪些,潍坊哪家招聘网站好?  广州美橙建站如何快速搭建多端合一网站?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?  Python文件管理规范_工程实践说明【指导】  如何在IIS管理器中快速创建并配置网站?  如何在阿里云虚拟服务器快速搭建网站?  相册网站制作软件,图片上的网址怎么复制?  如何在Windows 2008云服务器安全搭建网站?  建站主机选购指南:核心配置与性价比推荐解析  济南网站制作的价格,历城一职专官方网站?  手机网站制作与建设方案,手机网站如何建设?  网站制作模板下载什么软件,ppt模板免费下载网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。