Fork me on GitHub

angular中指令ng-if需要注意的问题


在工作中不止我一个人遇到控制器中的变量值改变了,但是没有及时的反应到页面上,当时遇到的时候我很头痛,现在想想真的自己知识还没到家,今天把这个问题好好的记录下来,希望遇到的这个问题人不在走弯路。

问题描述

  • html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <div class="container" ng-controller="checkboxCtrl">
    <div class="row">
    <form ng-if="show">
    <input type="checkbox" ng-model="allData" ng-change="all(allData)">
    <ul>
    <li ng-repeat="item in list">
    <input type="checkbox" ng-model="item.checked" ng-change="ck(item.checked)">
    </li>
    </ul>
    </form>
    <button type="button" ng-click="getShow()">点击</button>
    <pre>
    allData: {{allData}}
    current: {{list}}
    </pre>
    </div>
    </div>
  • js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <script src="../node_modules/angular/angular.js"></script>
    <script>
    angular.module('app', [])
    .controller('checkboxCtrl', ['$scope', function($scope){
    $scope.show = true;
    $scope.allData = false
    $scope.list = [
    {checked: false},
    {checked: false},
    {checked: false},
    ];
    // 点击按钮
    $scope.getShow = function() {
    $scope.show = !$scope.show;
    }
    // 全选方法
    $scope.all = function(data) {
    console.log(data);
    if (data) {
    for (var i =0; i< $scope.list.length; i++) {
    var cur = $scope.list[i];
    cur.checked = true
    }
    } else {
    for (var i =0; i< $scope.list.length; i++) {
    var cur = $scope.list[i];
    cur.checked = false
    }
    }
    }
    // 多选方法
    $scope.ck = function(item) {
    let count = 0;
    for (var i =0; i< $scope.list.length; i++) {
    var cur = $scope.list[i];
    if (cur.checked) {
    count++;
    }
    }
    if (count === $scope.list.length) {
    $scope.allData = true
    } else {
    $scope.allData = false
    }
    }
    }])
    </script>
  • 分析问题

    • form表单里面的内容是通过ng-if来控制显示隐藏的,而ng-if是移除或者生成节点,当一个元素被ng-if从DOM中移除,同它关联的作用域也会被销毁。而且当它重新加入DOM中时,会通过原型继承从它的父作用域生成一个新的作用域。
    • ng-ifng-model结合时,虽然自身的值改变了,但是与父级作用是隔离的,所以是改变不了值的变化的,因此会出现页面上的值没有变化
  • 解决问题

    • 方法1:在ng-model中绑定$parent.allData变量,这样更改的就是父级的值

      1
      2
      3
      4
      ...
      <form ng-if="show">
      <input type="checkbox" ng-model="$parent.allData" ng-change="all($parent.allData)">
      ...
    • 方法2:使用ng-show控制页面的显示隐藏,不产生新的作用域

  • demo
-------------本文结束感谢您的阅读-------------