隐藏时从$ scope中删除所有ng-model变量

时间:2015-05-15 22:13:52

标签: angularjs angular-directive

我的问题类似于this question中的问题,当我们知道要删除的范围变量时,这就有效。但是,我正在寻找一些通用的东西,比如删除该指令附加到的所有元素的变量,只要它们被隐藏。我尝试注入ngModel并尝试设置为null或删除,似乎不起作用。

这就是我想要的: plunk

myModule.directive('destroyY', function(){
         return{
          restrict:'A',
          require: '?ngModel',
          link: function(scope, elem, attrs, ngModel) {

            scope.$on('$destroy', function(){
             console.log(ngModel);

             ngModel=null; // doesn't work
             delete ngModel; // doesn't work

            }) 
          }
         }
        });

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:3)

具体而言,在您使用ng-if并使用require: "ngModel"的指令的情况下,您可以这样做:

 scope.$on("$destroy", function(){
    ngModel.$setViewValue(undefined);
 }

这里还要注意另一件事:

scope.$on("$destroy")范围被销毁时起作用 - 并非总是元素被“销毁”(或从DOM中删除)。在你的情况下,它可以工作,因为ng-if创建了一个子范围,但是,完全有可能一个元素被另一个指令删除,而没有它“生存”它被销毁的范围。在这种情况下,您可能希望使用elem.on("$destroy")

修改

实际上,正如评论中所指出的,这并不会删除实际的密钥 - 只需设置该密钥的值即可。如果你考虑一下,这是正确的做法,因为密钥可以是一个setter函数(ngModel supports setter/getter functions)。

虽然我建议不要这样做,但你仍然可以从范围中删除该属性,尽管这是一种丑陋的方法,显然不会被Angular所接受。

您需要获取父对象表达式(例如form)及其属性表达式(例如y),然后删除该属性。请注意,如果没有点符号("."),那么ngModel会设置被销毁范围的值,因此我们会关心它。为此,您需要使用$parse

var modelExp = attrs.ngModel;
var idxOfDot = modelExp.lastIndexOf(".");
var parentExp = modelExp.substring(0, idxOfDot);
var propExp = modelExp.substring(idxOfDot + 1);

var parsedParentExp = $parse(parentExp);

scope.$on("$destroy", function(){
   var p = parsedParentExp(scope);
   if (p){
      delete p[propExp];
   }
})