1. 程式人生 > >ionic 自定義指令無法獲取繫結值,ngModelController.$viewValue無法使用

ionic 自定義指令無法獲取繫結值,ngModelController.$viewValue無法使用

最近因為專案需要,自定義了一個外來鍵指令,用於選擇model中巢狀的model,可是在指令處於編輯狀態的時候獲取ng-model初始化值的時,在link函式中通過ngModelController獲取$viewValue無法獲取到,自己便通過另一個種方式解決了這個問題,雖然不是正規的解決方式,但是也算是解決了問題,在此分享出來,如果你遇到這個問題,或許可以參考,以下是解決方案:

首先說明一下以下的關於作用於的兩個問題

1、angular的作用域問題

angular應用可以有很多的作用域,每個控制器所控制的dom樹有其自己的獨立的作用域,作用域可以進行巢狀,最終的根作用域是angular的rootScope,除了根作用域之外,每一個作用都有自己的相應的$parent,作用域是可以繼承,這和js中的原型鏈有相同的思想

2、指令的作用域問題

每一個自定義的指令都會有一個自己獨立的作用域,且提供了獲取當前作用域的一個變數,不管是在controller或者link函式或其他函式中,都是可以獲取到的,指令的作用域也是有$parent的

上面說到,因為ngModelController不能正常解決ng-model值繫結的問題,因為沒有能正常獲取ngModelController.$viewValue的值,所以便通過作用進行手動獲取,雖然沒有具體查證,但是初步猜測ngModelController.$viewValue正式通過作用域巢狀的原理來進行獲取的

以下是最終解決方案:

scope.viewValue = ngModelController.$viewValue
?ngModelController.$viewValue: null; if(!scope.viewValue) { var viewValueAttrs = attrs['ngModel'].split('.'); switch(viewValueAttrs.length) { case 1: { try{ scope.viewValue = scope.$parent
[viewValueAttrs[0]]; }catch(e) { scope.viewValue = null; } break; } case 2:{ try{ scope.viewValue = scope.$parent[viewValueAttrs[0]][viewValueAttrs[1]]; }catch(e) { scope.viewValue = null; } break; } case 3: { try{ scope.viewValue = scope.$parent[viewValueAttrs[0]][viewValueAttrs[1]][viewValueAttrs[2]]; }catch(e) { scope.viewValue = null; } break; } default : { scope.viewValue = null; break; } } }
程式碼解讀:

首先會以正常的方式獲取,在沒有獲取到的情況之下,使用當前方案,link函式中通過attrs屬性獲取指令繫結屬性ngModel

這裡寫圖片描述

如上圖所示,ngModel屬性可能為幾層,所以在原始碼中進行處理,可能不止兩層,如aaa.bbbb.ccc.dddd形式
處理之後的ngModel屬性通過scope作用域來進行獲取值,
這裡寫圖片描述

此處注意,睜大眼睛,重點來了哦,這裡不能通過link函式中的scope屬性直接獲取ngModel屬性所繫結的那個值,要在向上取到一層$parent之後才能正常獲取,此處的scope屬性作為指令作用域是獨立的,不能通過向上查詢的方式獲取到值。所以要通過scope.\$parent即可解決,最終反向設值時使用ngModelController.\$setViewValue(viewValue)

對於angular指令的link,controller函式的如果不清楚,可以參考這裡