Search code examples
javascripthtmlangularjsangularjs-ng-href

AngularJs ng-href dynamic link with scope not updating/working


I am having a problem where an tag with an ng-href tag link with a scope parameter inside of it does update when the scope changes. I read in this answer (Why does the directive ng-href need {{}} while other directives don't?) that ng-href uses $observe which should change ng-href when the scope value is changed.

Here is the html links in question. It is has two buttons to change the year, a p tag to show the year (id=yearp), and a button for each month (with the links that are not working properly)

<button id="left" style="display:inline;">left </button>
<p id="yearp" style="display:inline;"> {{curyear}} </p>
<button id="right" style="display:inline;"> right </button><br/>

<a ng-href="#calendar/month/{{curyear}}-01-01"><button style="display:inline;"> January </button></a>
<a ng-href="#calendar/month/{{curyear}}-02-01"><button style="display:inline;"> February </button></a>
<a ng-href="#calendar/month/{{curyear}}-03-01"><button style="display:inline;"> March </button></a>
<a ng-href="#calendar/month/{{curyear}}-04-01"><button style="display:inline;"> April </button></a>
<a ng-href="#calendar/month/{{curyear}}-05-01"><button style="display:inline;"> May </button></a>
<a ng-href="#calendar/month/{{curyear}}-06-01"><button style="display:inline;"> June </button></a>
<a ng-href="#calendar/month/{{curyear}}-07-01"><button style="display:inline;"> July </button></a>
<a ng-href="#calendar/month/{{curyear}}-08-01"><button style="display:inline;"> August </button></a>
<a ng-href="#calendar/month/{{curyear}}-09-01"><button style="display:inline;"> September </button></a>
<a ng-href="#calendar/month/{{curyear}}-10-01"><button style="display:inline;"> October </button></a>
<a ng-href="#calendar/month/{{curyear}}-11-01"><button style="display:inline;"> November </button></a>
<a ng-href="#calendar/month/{{curyear}}-12-01"><button style="display:inline;"> December </button></a>

And the angular controller for this page looks like this

App.controller('yearController', function($scope){
    var cdt = new Date();
    $scope.curyear = cdt.getFullYear();
    $("#left").click(function(){
        $scope.curyear = $scope.curyear - 1;
        $("#yearp").text($scope.curyear);
    });
    $("#right").click(function(){
        $scope.curyear = $scope.curyear + 1;
        $("#yearp").text($scope.curyear);
    });
});

Now pressing the buttons prev and next correctly change the $scope.curyear and is updated in the yearp tag, but pressing any of the links will still take me to (if pressing January) "calendar/month/2015-01-01" regardless of what $scope.curyear is. Anyone have any input on why this is happening and how to fix it?

Thanks in advance!


Solution

  • The reason it's not updating is because your click callback is outside of the Angular $digest loop. But, you shouldn't be accessing the DOM in a controller for quite a few reasons which are detailed in Angular docs and in a number of StackOverflow tickets.

    Recommended Reading:

    Update your HTML to:

    <button id="left" ng-click="prevYear()" style="display:inline;">left </button>
    <p id="yearp" style="display:inline;"> {{curyear}} </p>
    <button id="right" ng-click="nextYear()" style="display:inline;"> right </button><br/>
    

    And your controller:

    App.controller('yearController', function($scope){
        var cdt = new Date();
        $scope.curyear = cdt.getFullYear();
        $scope.prevYear = function(){
            --$scope.curyear;
        }
        $scope.nextYear = function(){
            ++$scope.curyear;
        }
    });