sukesh
sukesh

Reputation: 2423

scope variable inside directive is not updating - angularjs

I have a simple directive for a table with pagination. The Pagination has a dropdown & a button. User can either select a page in the dropdown or click on the button to navigate. Say, the dropdown lists page numbers 1, 2, 3 and the selected page is 1. When user clicks on 'Next', the selected value in the dropdown should become 2.

Issue: When Next is clicked, though the scope variable SelectedPage is seen updated in the console, it is not reflecting in the view.

report.html:

<div>
<ul>       
   <li>
     <select ng-model="$scope.state.SelectedPage" ng-change="ShowPageResult()">
      <option ng-repeat="num in PageNumbers value="{{num}}">{{num}}</option>
     </select>
   </li>
   <li ng-click="ShowNextPage();"><a href=" #">Next</a></li>       
</ul>
<table>
...//some html
</table>
</div>

directive

app.directive('Report', function () {
    return {
        restrict: 'AE',            
        replace: 'true',
        templateUrl: '/views/report.html'            
    };
});

controller:

$scope.state={};
$scope.ShowPageResult = function () {
        GetReport($scope.state.SelectedPage);
    }
$scope.ShowNextPage = function () {
        $scope.state.SelectedPage = $scope.state.SelectedPage + 1;                
        GetReport($scope.state.SelectedPage);
    }

//get report data to bind to table
function GetReport(pageNumber) {
        $scope.UserReport = [];

        var promise = ReportsFactory.GetData();
        promise.then(function (success) {
            if (success.data != null && success.data != '') {                
                $scope.UserReport = success.data;                
                BindPageNumbers($scope.UserReport[0].TotalRows, pageNumber);              
            }            
        },
        function (error) {
            console.log(error);
        });
    }

  //bind page numbers to dropdown in pagination
    function BindPageNumbers(totalRows, selectedPage) {        
        $scope.PageNumbers = [];
        $scope.LastPageNumber = Math.ceil((totalRows / 10));
        for (var i = 1; i <= Math.ceil((totalRows / 10)) ; i++) {
            $scope.PageNumbers.push(i);
        }
        $scope.state.SelectedPage = selectedPage; //can see the no. becomes 2 here.            
    }

Upvotes: 0

Views: 1182

Answers (2)

logee
logee

Reputation: 5067

Try putting SelectedPage in an object. So in your controller

$scope.state = {
    SelectedPage: 1
};

You need to initialise the SelectedPage.

Then reference SelectedPage with state.SelectedPage in your controller and in your directive template:

<select ng-model="state.SelectedPage" ng-change="ShowPageResult()">

Because of javascript prototypical inheritance, the SelectedPage in your directive will be different to the one in your controller. See Understanding Scopes

And it's not clear to me why you're binding BindPageNumbers to your directive scope. Firstly, there is no controller in your directive so it never gets called there and there is no call in the template either. Second, BindPageNumbers is not bound to the parent scope so the directive wont get that function anyway.

Upvotes: 1

David Votrubec
David Votrubec

Reputation: 4156

My guess:

ng-change="ShowPageResult()" is declared in the directive template and because your directive declares its own scope, then it looks for the definition of ShowPageResult() in the directive's scope and not in the controller.

Therefore the change handler function is null and does nothing.

Upvotes: 1

Related Questions