AngularJS:ng-if |隐藏(已删除)ng-model变量未从$ scope中删除

时间:2014-06-04 16:30:29

标签: angularjs

我试图理解ng-if与ng-show的对比。 在阅读了文档并通过相关的stackoverflow问题here后,我理解ng-if删除了DOM元素,并且删除了ng-if中的范围变量。在'removed'ng中的ng-model变量-if元素不会出现在$ scope中。

来自Angular ng-if docs: -

  

请注意,使用ngIf删除元素时,其范围将被销毁   并且在恢复元素时创建新范围。范围   在ngIf中创建的,使用prototypal从其父作用域继承   遗产。这是一个重要的含义,如果使用ngModel   在ngIf中绑定到父级中定义的javascript原语   范围。

请考虑以下代码段: -

<!doctype html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.10/angular.min.js"></script>
  </head>
  <body  data-ng-app="myModule">    
    <div data-ng-controller="TestController">      
      <input name="first" type="number" data-ng-model="form.x" placeholder="Enter Number X"/>
      <input name="second" type="number" data-ng-if="form.x>5" data-ng-model="form.y" placeholder="Enter Number Y"/>
      <input type="button" value="Click" ng-click="save()"/>      
    </div>  
    <script type="text/javascript">     
        var myModule = angular.module("myModule",[]);
        myModule.controller("TestController",function($scope){
            $scope.form = {};
            $scope.form.x = 0;
            $scope.form.y = 0;
            $scope.save = function(){
                console.log($scope.form);
            };
        });             
    </script>
</html>

这是一个非常简单的用例 - 只有当first大于5时才显示第二个数字输入字段。

保存按钮单击委托控制器中的“保存”功能,该功能只打印出$ scope的'form'对象。

问题: -

输入1: - 输入x = 6和y = 2 输出1:{x:6,y:2}

输入2: - 输入x = 3 输出2:{x:3, y:2 }

我无法理解为什么'输出2'仍显示y = 2。如果它的DOM已被删除,那么输出不应该只是{x:3}?

如果我想从范围中删除(ngIf-removed)模型,我该怎么办?

由于

3 个答案:

答案 0 :(得分:5)

问题

为了进一步了解@Chandermani在评论中指出的内容,ng-if创建了一个 new 范围,它有自己的变量。但是,它原型继承自其父作用域,因此如果在现有父对象上设置属性,例如使用form.y进行的操作,则在销毁子作用域时,该属性不受影响

快速解决方案

您可以将另一个指令添加到与您设置ng-if的元素相同的元素,delete$destroy范围内的属性:

<强>指令

myModule.directive('destroyY', function(){
  return function(scope, elem, attrs) {
    scope.$on('$destroy', function(){
      if(scope.form.y) delete scope.form.y;
    }) 
  }
});

查看

<input ... data-ng-if="form.x>5" destroy-y .../>

Demo

注意:我看到@ user2334204发布了类似的内容。我决定发布这个,因为这里不需要检查x的值每个摘要

答案 1 :(得分:3)

您好:D您可以在&#34; x&#34;上设置观察者。变量,像这样:

$scope.$watch(function(){
      return $scope.form.x;
},function(){
      if($scope.form.x < 5) delete $scope.form.y;
});

虽然我不知道是否使用&#34;删除&#34;是一个很好的做法...

希望它适合你。

---- ---- EDIT

另一种方法:

<input ng-model="form.x" ng-change="check(form.x)">

在你的控制器中:

$scope.check = function(x){
        if(x < 5 ) delete $scope.form.y;
};

虽然我认为@Marc Kline选项更好。

答案 2 :(得分:0)

对于动态键,您可以定义如下指令:

myModule.directive('removeKey', function () {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {

        scope.$on('$destroy', function () {

            let attributes = scope.$eval(attrs.removeKey);

            if (scope.$parent[attributes.mainModel].hasOwnProperty(attributes.modelKey))
                delete scope.$parent[attributes.mainModel][attributes.modelKey];
        });
    }
  };
});

你的观点是这样的:

<div ng-if="condition === 0">
    <input ng-model="myFormJson.inputOne" remove-key='{"mainModel":"myFormJson","modelKey":"inputOne"}' />
</div>

<div ng-if="condition === 1">
    <input ng-model="myFormJson.inputTwo" remove-key='{"mainModel":"myFormJson","modelKey":"inputTwo"}' />
</div>