最近因为项目需要,自定义了一个外键指令,用于选择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函数的如果不清楚,可以参考这里
原文链接:https://www.f2er.com/angularjs/147493.html