Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng-repeat's element not updated on array modification

When I trying to update my array on ng-click in order to update my ng-repeat's directive items:

<li ng-repeat="itemL1 in mainMenuL1Arr"
    ng-click="selectL2menu(itemL1.name)">
  <i ng-class="getClass(itemL1.icon)"></i>
</li>

selectL2menu() defined on controller as:

$scope.selectL2menu = function selectL2menu(itemL1name){
        $scope.$apply(function () {
            $scope.mainMenuL2CurArr = $scope.mainMenuL2Obj[itemL1name];
        });
}

Right after click on 1st level menu item it should reveal 2nd level menu block with correspondent elements (by updating the array with correspondent values, see below). Here is 2nd level menu block I need to update on click:

<li ng-repeat="itemL2 in mainMenuL2CurArr"
    class="subMenuElemBlock"
    ng-class="{active: itemL2.selected}">
        <a href="#">
             <i ng-class="getClass(itemL2.icon)"></i>
             <span>{{itemL2.name}}</span>
        </a>
</li>

While click event triggered - my array successfully updated. Nevertheless ng-repeat directive not updated my 2nd level menu (base on updating array). I've tried to with (and without) using $apply function - same result (though using $apply error message appearing Error: $apply already in progress).

So, why my array being successfully updated on click not revealed on ng-repeat directive menu element?

I've read related posts (link, link, link) but did't find any working decision.

like image 262
Mikalaj Murziankou Avatar asked May 28 '13 16:05

Mikalaj Murziankou


2 Answers

Without seeing more of your controller code, it is difficult to determine what the problem might be. Here is a simplified working fiddle. I suggest you compare it to what you have.

Note that you don't need to call $scope.$apply() because the ng-click directive will do that for us automatically.

HTML:

<ul>
    <li ng-repeat="itemL1 in mainMenuL1Arr" ng-click="selectL2menu(itemL1.name)">
      {{itemL1.name}}</li>
</ul>
<ul style="margin-left: 20px">
    <li ng-repeat="itemL2 in mainMenuL2CurArr"><a href="#">
         <span>{{itemL2.name}}</span>
    </a>
    </li>
</ul>

JavaScript:

function MyCtrl($scope) {
    $scope.mainMenuL1Arr = [ {name: 'one'}, {name: 'two'} ];
    $scope.mainMenuL2Obj = { 
        one: [ {name: '1.1'}, {name: '1.2'} ],
        two: [ {name: '2.1'}, {name: '2.2'} ] };
    $scope.mainMenuL2CurArr = $scope.mainMenuL2Obj['one'];
    $scope.selectL2menu = function (itemL1name) {
        console.log(itemL1name);
        $scope.mainMenuL2CurArr = $scope.mainMenuL2Obj[itemL1name];
    };
}
like image 54
Mark Rajcok Avatar answered Sep 20 '22 17:09

Mark Rajcok


Can you try to make the $scope.$apply() after you add item in array like

$scope.array.push({id: 1, name: 'test'});
$scope.$apply();

Works fine for me, probably you have another function of a plugin or something like this, that blocking the scope apply, in my case I have a select2 and when select in field the apply is not fired

like image 33
Leonardo Salles Avatar answered Sep 18 '22 17:09

Leonardo Salles