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函式的如果不清楚,可以參考這裡