AngularJS ng-model在ng-if内部不起作用


206

这是显示问题的小提琴。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>

6
要解决此问题,可以使用ng-show =“ CONDITION”代替ng-if。它应该工作。
哈里·达斯

我认为现在这不再是一个问题,可以使用controllerAs吗?
jamiebarrow16'July

在使用带有隐式指令的指令时,我遇到了同样的问题,并在指令周围scope:false添加了ng-if元素-范围最初是绑定的,但是在观察者更新了其中一个范围值之后它们被分隔开了……
Aprillion

Answers:


223

ng-if与其他指令一样,该指令将创建子范围。请参阅下面的脚本(或此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一样修改对象的内部属性。


1
如何从主控制器功能中访问ng-if的作用域?有点令人沮丧。这是什么原因呢?
贾斯汀·卡尔森

没关系,@ sza只是回答了^问题。我会将此答案标记为正确,因为它可以解释我遇到问题的确切原因。
贾斯汀·卡尔森

21
这是一个原因,它在您的范围内使用包含对象而不是直接修改范围属性是很常见的,如示例中所指出:$scope.obj = {...}并且ng-model="obj.someProperty"克服了此限制。
wulftone

204

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

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

16
那么我就有了,ng-model="$parent.$parent.foo因为我已经在一个范围内了ng-repeat-这真的是最好的方法吗?
chovy

4
这确实令人困惑。这是为什么?为什么ng-hide没有自己的作用域?
Dominik Goltermann 2014年

5
Re @Gaul:大概是因为ng-hide / ng-show在当前DOM上运行,只是添加/删除了CSS类,而ng-if / ng-switch / ng-repeat都与DOM混在一起,并跟踪额外状态。似乎很明智。
trisweb 2014年

4
明智不是我用的词。
乔纳森·杜马因

3
将对象添加到原始范围,并更改该对象的属性。例如ng-model =“ myObject.property”。这将回避所有范围/ $ parent的不工作。谷歌“角点规则”的更多信息。
Asmor

50

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

<div ng-hide="testa">

3
为什么要ngIf创建子范围?对我来说似乎很奇怪。
freeall 2015年

5
注意zsong答案的评论。ng-hide不会改变html结构。它只是更改CSS样式。ng-if更为复杂:它会根据条件删除并插入html部分。它创建子范围来存储状态(至少它应该存储隐藏的html部分)。
Vasiliy Kevroletin

是的,为我工作
Basit

7

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

<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>

希望这对您有帮助


3

是的,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/


0

您可以这样操作,并且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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.