亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

AngularJS動(dòng)態(tài)菜單操作指令

 更新時(shí)間:2017年04月25日 14:19:47   作者:w-rain  
在我們創(chuàng)建一個(gè)angularJS應(yīng)用的時(shí)候,菜單往往往是不可或缺的元素之一。接下來通過本文給大家介紹AngularJS動(dòng)態(tài)菜單操作指令,感興趣的朋友一起學(xué)習(xí)吧

前言    

    在我們創(chuàng)建一個(gè)angularJS應(yīng)用的時(shí)候,菜單往往往是不可或缺的元素之一。也許在我們靜態(tài)菜單的時(shí)候不會(huì)發(fā)現(xiàn)在指令中操作菜單收縮、折疊展開沒有任何問題,因?yàn)槲覀冊(cè)诓僮髦埃撁嬖劁秩疽呀?jīng)完成,所以在指令里面通過element查找目標(biāo)元素可以成功。但是一旦我們的菜單的數(shù)據(jù)不是靜態(tài)而是通過后臺(tái)接口加載動(dòng)態(tài)數(shù)據(jù)渲染,我們會(huì)發(fā)現(xiàn)本來在靜態(tài)寫好的指令操作,在轉(zhuǎn)變?yōu)閯?dòng)態(tài)數(shù)據(jù)加載之后,怎么也沒法查找到想要的目標(biāo)元素。

    遇到如此問題,開始覺得好奇葩的,當(dāng)然這也是吐槽一下,還是得好好解決問題的,痛定失痛,決心好好理清思路,分析一下問題原因。首先我們先了解一下AngularJS的生命周期。

AngularJS的生命周期

    在AngularJS應(yīng)用啟動(dòng)前,它們會(huì)以HTML文本的形式保存在文本編輯器中。應(yīng)用啟動(dòng)后會(huì)進(jìn)行編譯和鏈接,作用域會(huì)同HTML進(jìn)行綁定,應(yīng)用可以對(duì)用戶在HTML中進(jìn)行的操作進(jìn)行實(shí)時(shí)響應(yīng)。AngularJS的生命周期主要有兩個(gè)主要階段:一個(gè)是編譯階段,一個(gè)是鏈接階段。

AngularJS生命周期-編譯階段

    在編譯階段,AngularJS會(huì)遍歷整個(gè)HTML文檔并根據(jù)JavaScript中的指令定義來處理頁面上聲明的指令。每一個(gè)指令模板中可能有另一個(gè)指令,另一個(gè)指令也有可能會(huì)有自己的模板。AngularJS調(diào)用HTML文檔根部的指令時(shí),會(huì)遍歷其中所有的模板,模板中可能含有模板的指令。如果一個(gè)元素已經(jīng)有一個(gè)含有模板的指令,永遠(yuǎn)不要對(duì)其用另一個(gè)指令進(jìn)行修飾,只有最高優(yōu)先級(jí)的指令中的模板會(huì)被編譯。

    一旦對(duì)指令和其中的子模板進(jìn)行遍歷或編譯,編譯后的模板會(huì)返回一個(gè)叫做模板函數(shù)的函數(shù)。在這個(gè)時(shí)候的DOM樹還沒有進(jìn)行數(shù)據(jù)綁定,此時(shí)對(duì)DOM樹操作只會(huì)有很少的性能開銷,ng-repeat和ng-transclude等內(nèi)置指令會(huì)在這個(gè)時(shí)候?qū)€未進(jìn)行數(shù)據(jù)綁定的DOM進(jìn)行操作。比如ng-repeat,它會(huì)遍歷指定的數(shù)組或?qū)ο?,在?shù)據(jù)綁定之前構(gòu)建對(duì)應(yīng)的DOM結(jié)構(gòu),然后將新的DOM(編譯后的DOM)傳遞給指令生命周期中的下一階段,鏈接階段。一個(gè)指令的DOM一旦編譯完成,就可以立即通過編譯函數(shù)對(duì)其進(jìn)行訪問,編譯函數(shù)的簽名包含有訪問指令聲明所在的元素(tElements)及該元素對(duì)其他屬性(tAttrs)的方法。

    compile返回對(duì)象或函數(shù),compile()函數(shù)負(fù)責(zé)對(duì)模板DOM進(jìn)行轉(zhuǎn)換,link()函數(shù)負(fù)責(zé)將作用域和DOM進(jìn)行轉(zhuǎn)換。

//...
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){
  //連接函數(shù)
 };
}
//...

 AngularJS生命周期-鏈接階段

    link函數(shù)創(chuàng)建可以操作DOM的指令,鏈接函數(shù)是可選的。定義了編譯函數(shù),返回鏈接函數(shù),當(dāng)兩個(gè)函數(shù)都定義了,編譯函數(shù)會(huì)重載鏈接函數(shù)。

//下面2種定義指令的放松在功能上是完全一樣的
angular.module('myApp',[])
.directive('myDirective', function (){
 return {
 pre: function (tElement, tAttrs, transclude){
 //在子元素被鏈接之前執(zhí)行,之后調(diào)用‘link'函數(shù)無法定位鏈接的元素
 
 },
 post: function (scope, iElement, iAttrs, controllers){
   //在子元素被鏈接之后執(zhí)行
 }
 }
});
angular.module('myApp',[])
.directive('myDirective', function (){
 return {
 link: function (scope, ele, attrs){
  return {
  pre: function (tElement, tAttrs, transclude){
  //在子元素被鏈接之前執(zhí)行,之后調(diào)用‘link'函數(shù)無法定位鏈接的元素
  },
  post: function (scope, iElement, iAttrs, controllers){
    //在子元素被鏈接之后執(zhí)行
  }
  }
 }
 }
});

    當(dāng)定義了編譯函數(shù)來取代鏈接函數(shù)時(shí),鏈接函數(shù)使我們能提供給返回對(duì)象的第二個(gè)方法,也就是postLink函數(shù)。鏈接函數(shù)會(huì)在模板編譯并同作用域進(jìn)行鏈接后被調(diào)用。

//鏈接函數(shù)簽名
link: function(scope, element, attrs){
 //操作DOM
}
//含require選項(xiàng), require someContainer
link: function(scope, element, attrs, someContainer){
 //在這里操作DOM,可以訪問require指定的控制器
}
  • scope--指令用來在其內(nèi)部的作用域;
  • element--參數(shù)代表實(shí)例元素,指使用此指令的元素;
  • atrrs--代表實(shí)例屬性,是一個(gè)由定義在元素上的屬性組成的標(biāo)準(zhǔn)化列表,可以在所有指令的鏈接函數(shù)間共享,會(huì)以javascript對(duì)象的形式進(jìn)行傳遞;
  • controller 參數(shù)指向require選項(xiàng)定義的控制器。沒有設(shè)置require選項(xiàng),controller的參數(shù)為undefined;

    控制器在所有的指令間共享,因此指令可以將控制器當(dāng)作通信通道(公共API),如果設(shè)置多個(gè)require,這個(gè)參數(shù)是一個(gè)控制器實(shí)例組成的數(shù)組,而不是一個(gè)單獨(dú)的控制器。

問題剖析

    在通過對(duì)AngularJS生命周期的理解,我們可以清晰地認(rèn)識(shí)到動(dòng)態(tài)菜單為什么綁定在鏈接階段上的DOM操作沒有成功,由于ng-repeat的原因,我對(duì)DOM樹操作沒找到DOM元素。因?yàn)樵诜庋b成一個(gè)菜單指令組件的時(shí)候,我內(nèi)部的菜單數(shù)據(jù)加載使用ng-repeat實(shí)現(xiàn),所以只有在這個(gè)時(shí)候才能在ng-repeat內(nèi)部綁定對(duì)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里面操作菜單邏輯的代碼沒有被觸發(fā),angularjs的檢測(cè)機(jī)制也沒用,因?yàn)閚g-repeat的原因?qū)е翫OM操作事件沒有被掛載到DOM上,所以想操作菜單不可能成功。但是,如果ng-repeat的內(nèi)容是靜態(tài)存在的,link函數(shù)里面的操作是可以實(shí)現(xiàn)的。

    修改后的寫法:

//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){
 //操作菜單的邏輯代碼
 }
 }
});

    修改之后我們將我們操作動(dòng)態(tài)加載的DOM結(jié)構(gòu)的指令放入ng-repeat中,此時(shí)邏輯正常執(zhí)行,在link函數(shù)中能打印出DOM結(jié)構(gòu)。

以上所述是小編給大家介紹的AngularJS動(dòng)態(tài)菜單操作指令,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 詳解AngularJS中自定義過濾器

    詳解AngularJS中自定義過濾器

    過濾器(filter)正如其名,作用就是接收一個(gè)輸入,通過某個(gè)規(guī)則進(jìn)行處理,然后返回處理后的結(jié)果。主要用在數(shù)據(jù)的格式化上,例如獲取一個(gè)數(shù)組中的子集,對(duì)數(shù)組中的元素進(jìn)行排序等
    2015-12-12
  • 詳解angular如何調(diào)用HTML字符串的方法

    詳解angular如何調(diào)用HTML字符串的方法

    這篇文章主要介紹了詳解angular如何調(diào)用HTML字符串的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • AngularJS中的DOM操作用法分析

    AngularJS中的DOM操作用法分析

    這篇文章主要介紹了AngularJS中的DOM操作,較為詳細(xì)的分析了AngularJS針對(duì)DOM操作的原理、實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-11-11
  • Angularjs上傳文件組件flowjs功能

    Angularjs上傳文件組件flowjs功能

    現(xiàn)在的項(xiàng)目,無論代銷,幾乎不會(huì)缺省的一個(gè)功能就是上傳下載功能,今天談一談使用AngularJS+bootsrtap下的上傳下載功能,需要的朋友參考下吧
    2017-08-08
  • AngularJS初始化過程分析(引導(dǎo)程序)

    AngularJS初始化過程分析(引導(dǎo)程序)

    這篇文章主要介紹了AngularJS初始化過程分析(引導(dǎo)程序),這一節(jié)解釋了AngularJS初始化的過程,以及需要的時(shí)候你該如何修改AngularJS的初始化,需要的朋友可以參考下
    2014-12-12
  • AngularJS輕松實(shí)現(xiàn)雙擊排序的功能

    AngularJS輕松實(shí)現(xiàn)雙擊排序的功能

    網(wǎng)上已經(jīng)有AngularJS比較多的相關(guān)教程了,那么這篇文章我們一起來看一個(gè)AngularJS雙擊排序的例子,對(duì)大家日常開發(fā)很有幫助的,有需要的可以參考借鑒。
    2016-08-08
  • Angular 向組件傳遞模板的兩種方法

    Angular 向組件傳遞模板的兩種方法

    這篇文章主要介紹了Angular 向組件傳遞模板的兩種方法,第一種方式<ng-content>第二種方式是NgTemplateOutlet 指令及各種使用方式介紹,需要的朋友可以參考下
    2018-02-02
  • AngularJs入門教程之環(huán)境搭建+創(chuàng)建應(yīng)用示例

    AngularJs入門教程之環(huán)境搭建+創(chuàng)建應(yīng)用示例

    這篇文章主要介紹了AngularJs入門教程之環(huán)境搭建+創(chuàng)建應(yīng)用的方法,較為詳細(xì)的分析了AngularJS的功能、下載及應(yīng)用創(chuàng)建方法,需要的朋友可以參考下
    2016-11-11
  • angular+webpack2實(shí)戰(zhàn)例子

    angular+webpack2實(shí)戰(zhàn)例子

    本篇文章主要介紹了angular+webpack2實(shí)戰(zhàn)例子,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • 詳解angular中如何監(jiān)控dom渲染完畢

    詳解angular中如何監(jiān)控dom渲染完畢

    AngularJs是Google開源的前端JS框架。使用AngularJs, 我們能夠容易地、健壯的開發(fā)出類似于Gmail一樣的單頁Web應(yīng)用。這篇文章主要介紹了詳解angular中如何監(jiān)控dom渲染完畢,有興趣的可以了解一下。
    2017-01-01

最新評(píng)論