0

I am writing a directive that needs to show a search box and a few values in a grid. Entering a search text could change the values in the grid.

http://jsfiddle.net/rtv2222/st55azbg/5/

<div ng-controller="MyCtrl">
  <my-directive values='some.values' onsearchtextchange='onsearchtextchange' searchtext='some.searchtext'></my-directive>
  </div>

  var demo = angular.module('demo', []);
  demo.directive('myDirective', function($parse) {
  return {
    restrict: "E",
    scope: {         
        values: '=',
        searchtext: '=',
        onsearchtextchange: '&'
    },
    template: '{{values.length}} <input ng-model="searchtext">',
    link:
    function(scope, element, attrs){
        scope.$watch('searchtext', function (tmpStr){
            setTimeout(function() {
                // if searchStr is still the same..
                // go ahead and retrieve the data
                if (tmpStr === scope.searchtext)
                {
                    scope.onsearchtextchange()(scope.searchtext);
                    console.log(scope.values.length);
                }
            }, 1000);
        });
    }
}
});

function MyCtrl ($scope) {
$scope.some = {};
$scope.some.values = [{a:1}, {a:2}];
$scope.some.searchtext = "";
$scope.onsearchtextchange = function(searchtext) {
    if (searchtext && searchtext.length != 0) {
        $scope.some.values = [{a:1}];
        console.log('values.length is:' + $scope.some.values.length);
    }
    else {
        $scope.some.values = [{a:1}, {a:2}];
        console.log('values.length is:' + $scope.some.values.length);
    }
}
};

I am binding the searchtext, onsearchtextchange callback and the values with an isolate scope to the directive. I $watch the searchtext and make a callback into the controller function which updates the list of values.

I however find that the directive scope does not reflect the change in the value of 'values' on the controller scope.

What should I do so that the child scope is updated whenever the callback updates the values on the controller scope ?

As you can see when you run the example, when the searchtext is changed, the onsearchtextchange callback is called and the controller scope.some.values is changed. The directive scope values is however still the old value.

Rajesh TV
  • 71
  • 6

2 Answers2

0

Adding a $scope.$apply() in my controller callback does the trick.

Rajesh TV
  • 71
  • 6
0

Instead of using setTimeout() you can use the AngularJS $timeout service, which goes along with a $scope.$apply() internally. This way, you don't need to call $scope.$apply() in you controller.

demo.directive('myDirective', function($parse, $timeout) {
  return {
    restrict: "E",
    scope: {         
        values: '=',
        searchtext: '=',
        onsearchtextchange: '&'
    },
    template: '{{values.length}} <input ng-model="searchtext">',
    link:
    function(scope, element, attrs){
        scope.$watch('searchtext', function (tmpStr){
            $timeout(function() {
                // if searchStr is still the same..
                // go ahead and retrieve the data
                if (tmpStr === scope.searchtext)
                {
                    scope.onsearchtextchange()(scope.searchtext);
                    console.log(scope.values.length);
                }
            }, 1000);
        });
      }
   };
});
ryeballar
  • 29,658
  • 10
  • 65
  • 74
  • Hi, I originally wrote that debounce code, I recommend now using the debounce option in angular. See my answer here: http://stackoverflow.com/a/18494567/1599609 – Josue Alexander Ibarra Nov 26 '15 at 01:20