10

I am trying to create a simple pagination directive with an isolated scope. For some reason when I manually change the value it gets a bit finnicky. Here is my problem:

When I page forward and backward, it works great. Awesome

When I enter a page into the field it works. Great

However, if I enter a page into the field and then try to go forward and backward, the ng-model seems to break after I enter a page into the field. I had it working when I did not isolate my scope but I am confused as to why it would break it. Here is my code:

HTML:

<paginate go-to-page="goToPage(page)" total-pages="results.hits.pages" total-hits="results.hits.total"></paginate>

Directive:

'use strict';

angular.module('facet.directives')
    .directive('paginate', function(){
        return {
            restrict: 'E',
            template: '<div class="pull-right" ng-if="(totalPages !== undefined) && (totalPages > 0)">'+
                '<span class="left-caret hoverable" ng-click="changePage(current-1)" ng-show="current > 1"></span>&nbsp;&nbsp;Page'+
                '&nbsp;&nbsp;&nbsp;<input type="number" ng-model="current" class="pagination-input" ng-keypress="enterPage($event)"/> of'+
                '&nbsp;&nbsp;&nbsp;{{totalPages}}&nbsp;&nbsp;'+
                '<span class="right-caret hoverable" ng-click="changePage(current+1)" ng-show="current < totalPages"></span>'+
            '</div>',
            scope: {
                goToPage: '&',
                totalPages: '=',
                totalHits: '='
            },
            link: function(scope) {
                scope.current = 1;
                scope.changePage = function(page) {
                    scope.current = page;
                    window.scrollTo(0,0);
                    scope.goToPage({page:page});
                };
                scope.enterPage = function(event) {
                    if(event.keyCode == 13) {
                        scope.changePage(scope.current);
                    }
                }
            }
        }
    });

What am I doing wrong?

1
  • Could you set up a jsFiddle or Plunkr? Commented Dec 18, 2013 at 5:27

2 Answers 2

15

Beware of ng-if - it creates a new scope. If you change it to just ng-show, your example would work fine. If you do want to use ng-if, create a object to store the scope variable current. Maybe something like scope.state.current?

scope.state = {
    current: 1
};

To avoid confusion like this, I always keep my bindings as something.something and never just something.

Edit: Good explanation here - http://egghead.io/lessons/angularjs-the-dot

Sign up to request clarification or add additional context in comments.

2 Comments

Holy s*** that video. It opened my eyes to so many "problems" me and my team had with some angular bindings. We attributed them to quirks of html inputs or whatever, but I'm pretty sure that the missing dot was the problem.
Oh, geez! I've been pulling my hair, why it would not work anymore. I forgot about that ng-if scope...
11

Please always try to use model rather than using primitive types while using the ng-model because of the javascript's prototypical hierarchies.

angular.module('facet.directives').directive('paginate', function () {
    return {
        restrict: 'E',
        replace: true,
        template: '<div class="pull-right discovery-pagination" ng-if="(totalPages !== undefined) && (totalPages > 0)">' +
            '<span class="left-caret hoverable" ng-click="changePage(current-1)" ng-show="current > 1"></span>&nbsp;&nbsp;Page' +
            '&nbsp;&nbsp;&nbsp;<input type="number" ng-model="current.paging" class="pagination-input" ng-keypress="enterPage($event)"/> of' +
            '&nbsp;&nbsp;&nbsp;{{totalPages}}&nbsp;&nbsp;' +
            '<span class="right-caret hoverable" ng-click="changePage(current+1)" ng-show="current < totalPages"></span>' +
            '</div>',
        scope: {
            goToPage: '&',
            totalPages: '=',
            totalHits: '='
        },
        link: function(scope) {
            scope.current = {paging:1};
            scope.changePage = function(page) {
                scope.current.paging = page;
                window.scrollTo(0, 0);
                scope.goToPage({ page: page });
            };
            scope.enterPage = function(event) {
                if (event.keyCode == 13) {
                    scope.changePage(scope.current.paging);
                }
            };
        }
    };
}); 

Hope this will solve your problem :)

For detail about this, please go through Understanding-Scopes

1 Comment

"If you don't have a dot, you're doing it wrong" Lightbulb! youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.