前言

在我们创建一个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指定的控制器
}
控制器在所有的指令间共享,因此指令可以将控制器当作通信通道(公共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操作指令
# 绑定
# 遍历
# 是一个
# 加载
# 会有
# 在这个
# 会在
# 对其
# 会以
# 小编
# 自己的
# 文档
# 在这里
# 还没有
# 也有
# 不可能
# 多个
# 在此
# 没有任何
# 我对
相关文章:
如何用好域名打造高点击率的自主建站?
网站制作知乎推荐,想做自己的网站用什么工具比较好?
如何续费美橙建站之星域名及服务?
,网站推广常用方法?
Bpmn 2.0的XML文件怎么画流程图
建站168自助建站系统:快速模板定制与SEO优化指南
建站之星多图banner生成与模板自定义指南
如何通过主机屋免费建站教程十分钟搭建网站?
如何在七牛云存储上搭建网站并设置自定义域名?
制作网站的过程怎么写,用凡科建站如何制作自己的网站?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
建站之星2.7模板快速切换与批量管理功能操作指南
枣阳网站制作,阳新火车站打的到仙岛湖多少钱?
如何通过WDCP绑定主域名及创建子域名站点?
宿州网站制作公司兴策,安徽省低保查询网站?
建站之家VIP精选网站模板与SEO优化教程整合指南
湖北网站制作公司有哪些,湖北清能集团官网?
高防服务器租用如何选择配置与防御等级?
免费ppt制作网站,有没有值得推荐的免费PPT网站?
网站制作的步骤包括,正确网址格式怎么写?
成都网站制作公司哪家好,四川省职工服务网是做什么用?
如何快速完成中国万网建站详细流程?
香港服务器如何优化才能显著提升网站加载速度?
网站制作员失业,怎样查看自己网站的注册者?
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
如何通过老薛主机一键快速建站?
如何通过可视化优化提升建站效果?
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
TestNG的testng.xml配置文件怎么写
合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?
免费网站制作appp,免费制作app哪个平台好?
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
,南京靠谱的征婚网站?
javascript中对象的定义、使用以及对象和原型链操作小结
网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?
如何在景安云服务器上绑定域名并配置虚拟主机?
建站之星安装失败:服务器环境不兼容?
如何生成腾讯云建站专用兑换码?
山东云建站价格为何差异显著?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
建站之星如何取消后台验证码生成?
电脑免费海报制作网站推荐,招聘海报哪个网站多?
如何在Ubuntu系统下快速搭建WordPress个人网站?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?
如何快速使用云服务器搭建个人网站?
C#如何在一个XML文件中查找并替换文本内容
南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?
怀化网站制作公司,怀化新生儿上户网上办理流程?
*请认真填写需求信息,我们会在24小时内与您取得联系。