9

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.

Community
  • 1
  • 1
Mikalaj Murziankou
  • 765
  • 2
  • 6
  • 9

3 Answers3

5

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];
    };
}
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • 2
    Mark, I found your answer [here](http://stackoverflow.com/questions/14453216/using-the-same-controller-on-different-elements-to-refer-to-the-same-object) - exactly I need. The problem was when I tried to use same controller on two different elements (in other words I used ng-controller with same name wrongly trying to share data between two elements) - that is why updated array was on it's own scope. Thank a lot for spending time on my issue! Also thanks for the fiddle! – Mikalaj Murziankou May 28 '13 at 18:17
3

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

Leonardo Salles
  • 841
  • 6
  • 4
  • If I could, i would give you more than 1 upvote on this because I have been stuck on this issue for so dam long. Thanks !! – Maddy Feb 11 '19 at 18:56
0

Have you tried changing the selectL2Menu function to:

$scope.selectL2menu = function (itemL1name){
    $scope.mainMenuL2CurArr = $scope.mainMenuL2Obj[itemL1name];
}
Mike Pugh
  • 6,787
  • 2
  • 27
  • 25