Chris Dutrow
Chris Dutrow

Reputation: 50362

Wait for child component's update on binding to propagate to the parent in AngularJS

Am new to AngularJS. Am trying to build a component for paging that updates the current page. The problem I am having is that when the component makes a change to a value that has two-way bindings. The new value is not immediately available to the parent.

Is there something I should do in order to wait for the binding value to update? Or is this a patterning issue where I should be taking a different approach to solve the problem?

Component - paging.js

angular.module('someModule')
.component('paging', {
bindings: {
  page:   '=',
  getNextPage: '='  // <- Side note: This is a function, I had problems using the '&' binding
},
controller: function($scope) {
    var $ctrl = this;

    $ctrl.nextPage = function () {
      $ctrl.page++;
      $ctrl.getNextPage();   // <-- Parent will still have the old value for 'page'

      // THIS WOULD WORK, PARENT WOULD HAVE THE UPDATED VALUE FOR 'page'
      // setTimeout(function(){
      //   $ctrl.action();  
      // }, 1000);

      // COULD ALSO PASS THE VALUE THIS WAY
      // $ctrl.action($ctrl.page); 
    }

});

Parent controller

...
  $scope.getNextPage = function () {
      $scope.page; // <- This still has the old value 
      ...
  }

...

Upvotes: 3

Views: 462

Answers (1)

The.Bear
The.Bear

Reputation: 5855

Firstly, check this jsFiddle where you can see FOUR different options of binding to for your page index.

Inspecting your posted code, I don't see anything wrong, probably your problem is in the HTML template.

OPTION 1: Bind page variable and increase it inside the component

HTML:

<div ng-controller="parentCtrl">
    <paging page="page"></paging>
</div>

CONTROLLER:

function parentCtrl($scope) {
    $scope.page = 1;
}

COMPONENT:

var pagingComponent = {
    bindings: {
        page: '='
    },
    template: '<div><button ng-click="$ctrl.nextPage();">Next Page</button></div>',
    controller: function() {
        var $ctrl = this;

        $ctrl.nextPage = function() {
           $ctrl.page++;
        };
    }
}

OPTION 2: Bind getNextPage() function form parent controller

HTML:

<div ng-controller="parentCtrl">
    <paging get-next-page="getNextPage()"></paging>
</div>

CONTROLLER:

function parentCtrl($scope) {
    $scope.page = 1;
    $scope.getNextPage = function(page) {
        $scope.page++;
    }
}

COMPONENT:

var pagingComponent = {
    bindings: {
        getNextPage : '&'
    },
    template: '<div><button ng-click="$ctrl.nextPage();">Next Page</button></div',
    controller: function() {
        var $ctrl = this;

        $ctrl.nextPage = function() {
           $ctrl.getNextPage();
        };
    }
} 

Upvotes: 2

Related Questions