【问题标题】:Angularjs ng-model doesn't work inside ng-ifAngularjs ng-model 在 ng-if 中不起作用
【发布时间】:2019-08-06 14:29:17
【问题描述】:

这是显示问题的小提琴。 http://jsfiddle.net/Erk4V/1/

如果我在 ng-if 中有一个 ng-model,则该模型无法按预期工作。

我想知道这是一个错误还是我误解了正确的用法。

<div ng-app >
    <div ng-controller="main">

        Test A: {{testa}}<br />
        Test B: {{testb}}<br />
        Test C: {{testc}}<br />

        <div>
            testa (without ng-if): <input type="checkbox" ng-model="testa" />
        </div>
        <div ng-if="!testa">
            testb (with ng-if): <input type="checkbox" ng-model="testb" />
        </div>
        <div ng-if="!someothervar">
            testc (with ng-if): <input type="checkbox" ng-model="testc" />
        </div>

    </div>
</div>

【问题讨论】:

  • 对于解决方法,您可以使用 ng-show="CONDITION" 而不是 ng-if。它应该可以工作。
  • 我认为这不再是一个问题,现在人们可以使用controllerAs?
  • 我在使用带有隐式 scope:false 的指令时遇到了同样的问题,我在指令周围添加了 ng-if 元素 - 范围最初是绑定的,但在观察者更新其中一个之后它们变得分离范围值...

标签: angularjs


【解决方案1】:

ng-if 指令与其他指令一样创建子作用域。请参阅下面的脚本(或this jsfiddle

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js"></script>

<script>
    function main($scope) {
        $scope.testa = false;
        $scope.testb = false;
        $scope.testc = false;
        $scope.obj = {test: false};
    }
</script>

<div ng-app >
    <div ng-controller="main">
        
        Test A: {{testa}}<br />
        Test B: {{testb}}<br />
        Test C: {{testc}}<br />
        {{obj.test}}
        
        <div>
            testa (without ng-if): <input type="checkbox" ng-model="testa" />
        </div>
        <div ng-if="!testa">
            testb (with ng-if): <input type="checkbox" ng-model="testb" /> {{testb}}
        </div>
        <div ng-if="!someothervar">
            testc (with ng-if): <input type="checkbox" ng-model="testc" />
        </div>
        <div ng-if="!someothervar">
            object (with ng-if): <input type="checkbox" ng-model="obj.test" />
        </div>
        
    </div>
</div>

因此,您的复选框会更改子范围内的 testb,但不会更改外部父范围。

注意,如果要修改父作用域中的数据,则需要修改对象的内部属性,就像我添加的最后一个 div 中一样。

【讨论】:

  • 如何从主控制器功能中访问 ng-if 的范围?有点沮丧。这是什么原因?
  • 没关系,@sza 刚刚回答了那个 ^ 问题。不过,我会将此答案标记为正确,因为它解释了我遇到问题的确切原因。
  • 这是在作用域上使用包含对象而不是直接修改作用域属性相当普遍的原因之一,如示例中所指出的:$scope.obj = {...}ng-model="obj.someProperty" 克服了这个限制。
【解决方案2】:

您可以像这样使用$parent 来引用父作用域中定义的模型

<input type="checkbox" ng-model="$parent.testb" />

【讨论】:

  • 那么我有ng-model="$parent.$parent.foo,因为我已经在一个带有ng-repeat 的范围内——这真的是最好的方法吗?
  • 这真是令人困惑。这是为什么?为什么 ng-hide 没有自己的作用域?
  • Re @Gaul:大概是因为 ng-hide/ng-show 在当前的 DOM 上运行并且只是添加/删除一个 CSS 类,而 ng-if/ng-switch/ng-repeat 全部搞砸了DOM 并跟踪额外的状态。似乎很明智。
  • 明智不是我使用的词
  • 将对象添加到原始范围,并更改该对象的属性。例如ng-model="myObject.property"。这将回避所有范围/$parent 的空洞。谷歌“角点规则”了解更多信息。
【解决方案3】:

您可以使用ngHide (或 ngShow) 指令。它不像 ngIf 那样创建子作用域。

<div ng-hide="testa">

【讨论】:

  • 为什么ngIf 然后创建一个子作用域?我觉得很奇怪。
  • 关注zsong答案的cmets。 ng-hide 不会改变 html 结构。它只是改变 css 样式。 ng-if 更复杂:它根据条件删除和插入 html 部分。它创建子范围来存储状态(至少它应该存储隐藏的 html 部分)。
  • 是的,为我工作
【解决方案4】:

我们在许多其他情况下都有这种情况,我们在内部决定始终为控制器/指令提供一个包装器,这样我们就不需要考虑它了。 这是您使用我们的包装器的示例。

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js"></script>

<script>
    function main($scope) {
        $scope.thisScope = $scope;
        $scope.testa = false;
        $scope.testb = false;
        $scope.testc = false;
        $scope.testd = false;
    }
</script>

<div ng-app >
    <div ng-controller="main">

        Test A: {{testa}}<br />
        Test B: {{testb}}<br />
        Test C: {{testc}}<br />
        Test D: {{testd}}<br />

        <div>
            testa (without ng-if): <input type="checkbox" ng-model="thisScope.testa" />
        </div>
        <div ng-if="!testa">
            testb (with ng-if): <input type="checkbox" ng-model="thisScope.testb" />
        </div>
        <div ng-show="!testa">
            testc (with ng-show): <input type="checkbox" ng-model="thisScope.testc" />
        </div>
        <div ng-hide="testa">
            testd (with ng-hide): <input type="checkbox" ng-model="thisScope.testd" />
        </div>

    </div>
</div>

希望这会有所帮助, 伊夏

【讨论】:

    【解决方案5】:

    是的,ng-hide(或 ng-show)指令不会创建子作用域。

    这是我的做法:

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js"></script>
    
    <script>
        function main($scope) {
            $scope.testa = false;
            $scope.testb = false;
            $scope.testc = false;
            $scope.testd = false;
        }
    </script>
    
    <div ng-app >
        <div ng-controller="main">
    
            Test A: {{testa}}<br />
            Test B: {{testb}}<br />
            Test C: {{testc}}<br />
            Test D: {{testd}}<br />
    
            <div>
                testa (without ng-if): <input type="checkbox" ng-model="testa" />
            </div>
            <div ng-if="!testa">
                testb (with ng-if): <input type="checkbox" ng-model="$parent.testb" />
            </div>
            <div ng-show="!testa">
                testc (with ng-show): <input type="checkbox" ng-model="testc" />
            </div>
            <div ng-hide="testa">
                testd (with ng-hide): <input type="checkbox" ng-model="testd" />
            </div>
    
        </div>
    </div>
    

    http://jsfiddle.net/bn64Lrzu/

    【讨论】:

      【解决方案6】:

      您可以这样做,并且您的 mod 功能将完美运行,如果您需要代码笔,请告诉我

        <div ng-repeat="icon in icons">                   
                      <div class="row" ng-if="$index % 3 == 0 ">
                          <i class="col col-33 {{icons[$index + n].icon}} custom-icon"></i>
                          <i class="col col-33 {{icons[$index + n + 1].icon}} custom-icon"></i>
                          <i class="col col-33 {{icons[$index + n + 2].icon}} custom-icon"></i>
                      </div>
               </div>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多