0

I have this piece of HTML:

<div ng-switch="view">
    <div ng-switch-when="products">
        <input class="form-control" placeholder="Search" ng-model="searchText" />
        <ul ng-show="products && products.length > 0">
            <li class="head">
                <div class="column col-select"><input type="checkbox" ng-model="$parent.allSelected" ng-change="$parent.selectAll($parent.allSelected)" /></div>
                <div class="column col-name">Name</div>
                <div class="column col-code">Code</div>
                <div class="column col-stock">Stock</div>
                <div class="column col-code">Price</div>
                <div class="column col-buttons"></div>
            </li>
            <li ng-repeat="p in ($parent.shownProducts = (products | filter: searchText))">
                <div class="column col-select"><input type="checkbox" ng-model="p.selected" ng-change="select(p.selected)" /></div>
                <div class="column col-name">{{ p.name }}</div>
                <div class="column col-code">{{ p.code }}</div>
                <div class="column col-stock">{{ p.stock }}</div>
                <div class="column col-code">{{ p.price | currency: '$' : 2 }}</div>
                <div class="column col-buttons">
                    <button class="btn btn-edit" ng-click="goTo('edit', $index)"><i class="fa fa-pencil"></i></button>
                    <button class="btn btn-delete" ng-click="goTo('delete', $index)"><i class="fa fa-trash"></i></button>
                </div>
            </li>
        </ul>
    </div>
</div>

In my Angular controller:

$scope.products = [{ name: 'Test1' }, { name: 'Test2' }];

$scope.select = function (value) {
    if (!value) {
        $scope.allSelected = value;
        return;
    }

    var selCount = 0;
    for (var i in $scope.shownProducts) {
        if ($scope.shownProducts[i].selected) selCount++;
    }

    if (selCount == $scope.shownProducts.length) $scope.allSelected = true;
};

$scope.selectAll = function (value) {
    for (var i in $scope.shownProducts) {
        $scope.shownProducts[i].selected = value;
    }
};

This piece of code works BUT:

  • Header (li.head) must use $parent scope to access $scope service otherwise model is not updating though initial value is set correctly.
  • Ng-repeat scope does not use $parent but it works fine

It looks inconsistent for me. I understand that ng-repeat creates a child scope but why does it not require $parent then? And why is $parent required though it is outside of ng-repeat definition?

UPDATE:

The code I published was a part of ng-switch so I put that as well. shownProducts is an array which contains items filtered by search text. I added that control to HTML. I also added array of products to $scope.

Dmitry Istomin
  • 485
  • 1
  • 4
  • 8

2 Answers2

0

DEMO - http://plnkr.co/edit/0TpaUYqgaWYlGTdQ2KJN?p=preview

JS:

$scope.select = function (value) {
    if (!value) {
        $scope.allSelected = value;
        return;
    }

    var selCount = 0;
    for (var i in $scope.shownProducts) {
        if ($scope.shownProducts[i].selected) selCount++;
    }

    if (selCount == $scope.shownProducts.length) $scope.allSelected = true;
  };

  $scope.selectAll = function (value) {
      for (var i in $scope.shownProducts) {
          $scope.shownProducts[i].selected = value;
      }
  };

  $scope.products = [{"name":1, "code":"001","stock":"abc","price":500},{"name":2, "code":"002","stock":"xyz","price":1000}];
  $scope.shownProducts = $scope.products;

HTML:

No need to use $parent. Remove it and everything works fine.

<ul ng-show="products && products.length > 0">
  <li class="head">
      <div class="column col-select"><input type="checkbox" ng-model="allSelected" ng-change="selectAll(allSelected)" /></div>
      <div class="column col-name">Name</div>
      <div class="column col-code">Code</div>
      <div class="column col-stock">Stock</div>
      <div class="column col-code">Price</div>
      <div class="column col-buttons"></div>
  </li>
  <li ng-repeat="p in shownProducts = (products | filter: searchText)">
      <div class="column col-select"><input type="checkbox" ng-model="p.selected" ng-change="select(p.selected)" /></div>
      <div class="column col-name">{{ p.name }}</div>
      <div class="column col-code">{{ p.code }}</div>
      <div class="column col-stock">{{ p.stock }}</div>
      <div class="column col-code">{{ p.price | currency: '$' : 2 }}</div>
      <div class="column col-buttons">
          <button class="btn btn-edit" ng-click="goTo('edit', $index)"><i class="fa fa-pencil"></i></button>
          <button class="btn btn-delete" ng-click="goTo('delete', $index)"><i class="fa fa-trash"></i></button>
      </div>
  </li>
</ul>
softvar
  • 17,917
  • 12
  • 55
  • 76
0

The problem was ng-switch which creates a new scope therefore I have to use $parent to access the parent scope where everything is declared.

angularjs - ng-switch does not bind ng-model

Community
  • 1
  • 1
Dmitry Istomin
  • 485
  • 1
  • 4
  • 8