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

2eafrhcq  于 2023-11-16  发布在  Angular
关注(0)|答案(4)|浏览(135)

我正在尝试理解ng-if和ng-show的工作原理。在阅读文档和相关的stackoverflow问题here之后,我理解了ng-if删除了DOM元素,并且删除了ng-if中的作用域变量。即,“删除”ng-if元素中的ng-model变量不会出现在$scope中。
关于Angular ng-if docs
请注意,当使用ngIf删除一个元素时,它的作用域会被销毁,并在恢复元素时创建一个新的作用域。在ngIf中创建的作用域使用原型继承继承从其父作用域继承。这一点的一个重要含义是,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>

字符串
这是一个非常简单的用例-仅当第一个数字大于5时才显示第二个数字输入字段。
单击保存按钮将委托给控制器中的“保存”功能,该功能仅打印出$scope的“form”对象。

* 问题:-*

输入1:-输入x=6和y=2输出1:{x:6,y:2}
输入2:-输入x=3输出2:{x:3,y:2}
我不明白为什么“output 2”仍然显示y =2。如果它的DOM已经被删除,输出不应该只是{x:3}吗?
如果我想从作用域中删除(ngIf-removed)模型,我应该怎么做?
谢谢

zysjyyx4

zysjyyx41#

我用ng-show代替ng-if,在我的情况下,它的工作原理是一样的。

y53ybaqx

y53ybaqx2#

问题
为了进一步解释@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的值不必在每个摘要中都检查

yuvru6vn

yuvru6vn3#

你好:D你可以在你的“x”变量上设置一个监视器,类似于这样:

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

字符串
虽然我不知道使用“删除”是一个好的做法.
希望对你有用。

  • 编辑-
    另一种方法:
<input ng-model="form.x" ng-change="check(form.x)">


在您的控制器中:

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


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

f3temu5u

f3temu5u4#

对于动态键,你可以定义一个如下的指令:

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>

相关问题