2

I need to call a function in my directive when the value of variable in the parent controller changes. I tried adding a watch (I'm obviously doing it wrong) because nothing happens when the value changes. Here is the directive:

    angular.module('ssq.shared').directive('checkboxPicklist', function() {
    return {
        restrict: 'E',
        templateUrl: '/Scripts/app/Shared/directives/checkboxPicklist.html',
        replace: true,
        scope: {
            itemId: '=',
            list: '=',
            nameProp: '=',
            title: '@',
            searchPlaceholder: '@',
            callbackFn: '&',
            callMore: '&',
            clear: '='
        },

        link: function (scope, element, attrs) {
            scope.query = '';
            var parent = scope.$parent;
            var clear = parent.clear;
            scope.$watch(clear, function () {
                if (clear == true) {
                    this.clearAll();
                }
            })
            var child = element.find('.dropdown-menu');
            child.on({
                'click': function (e) {
                    e.stopPropagation();
                }
            });


            var selectedItemFn = function (item) {
                return item.selected;
            };

            scope.getSelectedCount = function () {
                return _.filter(scope.list, selectedItemFn).length;
            };
            scope.loadMore = function () {
                scope.callMore();
            };

            scope.allSelected = function(list) {
                var newValue = !scope.allNeedsMet(list);
                _.each(list, function(item) {
                    item.selected = newValue;
                    scope.callbackFn({ object: item });
                });
            };

            scope.allNeedsMet = function(list) {

                var needsMet = _.reduce(list, function(memo, item) {
                    return memo + (item.selected ? 1 : 0);
                }, 0);
                if (!list) {
                    return (needsMet === 0);
                }
                return (needsMet === list.length);
            };

            function clearAll() {
                _.each(list, function (item) {
                    item.selected = false;
                })
            }
        }

    };
});

Here is where I am trying to watch the variable:

            var parent = scope.$parent;
            var clear = parent.clear;
            scope.$watch(clear, function () {
                if (clear == true) {
                    this.clearAll();
                }
            })

Here is the function in my parent controller that changes the value of "clear"

    $scope.clearFilters = function (clear) {

    $scope.clear = true;

    $scope.form.selected.services = [];
    $scope.form.picked.areas = [];
    $scope.form.certified.verifications = [];
    $scope.form.subscribed.subscriptions = [];
    $scope.form.OperatorBusinessUnitID = null;
    $scope.form.OperatorBusinessUnitID = null;
};

I tried setting an attribute called "clearFilter" and assigning the variable to it, but the watch still doesn't trigger:

            scope.$watch(attrs.clearFilter, function (value) {
                if (value == true) {
                    this.clearAll();
                }
            });

                            <checkbox-picklist data-item-id="'servicesPicklist'"
                                           data-search-placeholder="Search Services"
                                           data-list="services"
                                           data-title="Service(s)"
                                           data-name-prop="'vchDescription'"
                                           data-callback-fn="addService(object)"
                                           call-more="loadMoreServices()"
                                           clear-filter="clear">

                        </checkbox-picklist>

I'm not really sure if I am calling the function correctly. scope.$parent above does get the initial value of the variable from the parent scope, but once it changes, it never updates.

EDIT:What I have discovered is the normal scope.$watch('clear', function...) is not working it seems because the directive is in "ssq.shared" module which is injected in my my Main Module "myModule" (see below), so even though the page the directive is on uses my 'GeneralSearchCtrl', I cannot get the watch to work on the variable located in 'GeneralSearchCtrl'. If I use scope.$parent.clear I can see the value of the variable, but I cannot seem to set a watch on it.

My module injection code:

var app = angular.module('myModule', ['ui.bootstrap', 'checklist-model', 'ssq.shared', 'ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.pagination', 'ui.grid.selection', 'ui.grid.exporter', 'ui.grid.autoResize', 'ui.router', 'cgBusy', 'ui.mask', 'ngFileUpload', 'ngSanitize']);

The page where the directive lives uses:

<div ng-app="myModule" ng-controller="GeneralSearchCtrl">

I am unable to get a watch on the variable located in GeneralSearchCtrl.

Any assistance is greatly appreciated!!!!

3 Answers 3

1

Add a watch for the $scope value and call the function,

scope.$watch('clear', function(newValue, oldValue) {
if (newValue) {
  this.clearAll();
}
});
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, but the watch in the directive never gets triggered once the directive has been rendered to the screen. Changing the variable in the parent controller does nothing in the directive.
I can't figure it out from the SO you directed me to. I'm still looking at it, thanks.
I think I'm not understanding it from the example is because in the example they are trying to use the directive to update the parent scope. I'm trying to update the directive when the parent scope changes.
The watch still doesn't work. please see my edits. Thanks for your help!
|
1
scope.$watch(clear, function () {
  if (clear == true) {
    this.clearAll();
  }
})

This.clearAll() doesn't exist in the scope of your $watch function. Simply calling clearAll() should work better.

The signature of the watch function is not correct.

scope.$watch('clear', function (new, old) {}

1 Comment

The watch, even with the corrected signature does not work. Please see my edits. Thanks for your help!
0

As it turns out, the problem was that the directive had scope:{...} in its definition which stopped the "normal" scope.$watch('clear', function...) from working. I had to add clear: '=' to the scope list like so:

            replace: true,
        scope: {
            itemId: '=',
            list: '=',
            nameProp: '=',
            title: '@',
            searchPlaceholder: '@',
            callbackFn: '&',
            callMore: '&',
            clear: '='
        },

Then clear="clear" to the directive like so:

                            <checkbox-picklist data-item-id="'servicesPicklist'"
                                           data-search-placeholder="Search Services"
                                           data-list="services"
                                           data-title="Service(s)"
                                           data-name-prop="'vchDescription'"
                                           data-callback-fn="addService(object)"
                                           call-more="loadMoreServices()"
                                           clear="clear">

                        </checkbox-picklist>

Then in the directive I had to add the watch like this for it work:

                scope.$watch('$parent.clear', function (newValue, oldValue) {
                if (newValue == true) {
                 clearAll();
                alert('it works!');
                }
            })

I really hope this helps someone else as this was difficult for me to figure out. Happy coding!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.