0

I've developed a custom angular directive to clear a notifications array (defined in controller using controllerAs 'this' syntax), when a button is clicked and then when a confirm button is clicked on a dialog that appears.

So the process is:

click on 'Clear Notifications'  >  dialog appears  >  click on 'Confirm'  >  clear array

Alternatively, in the same directive I've defined that if 'Cancel' is clicked on when the dialog appears, the array is not affected.

I've done this using an $mdMDialog from angular material, all within the directive code.

However, even though the model is clearly being affected as a result of confirming array clearance, the view does not update with various methods, including wrapping the directive function in $scope.$apply and adding a $scope.$apply callback function in the controller, injected as an argument in the directive link function.

I initially had this function within the controller and it worked fine, but due to moving it into a directive, the view no longer updates when the model changes.

Example similar to my app in JSFiddle: http://jsfiddle.net/c9v83vo4/7/.

(I've included a commented-out controller method to demonstrate.)

-

HTML:

<md-list-item ng-repeat="notification in notifications.shownNotifications | orderBy:notifications.sortProperty " ng-click="notifications.selectedNotification=notification; notification.read=true" ng-class=" { 'active': notifications.selectedNotification==notification, 'unread': notification.read == false } " class="md-3-line notification-item" md-ink-ripple="#fff">

Controller:

app.controller('notificationsController', function($scope, $state, $http, $document, $mdDialog, $filter, $timeout, $mdToast) {

var main = this;

this.test = 'TEST';

this.selectedNotification = null;
this.notifications = [
    {
        title: 'Notification One',
        description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu nisl nec quam iaculis aliquet. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce felis leo, ornare nec pharetra non, elementum non dui. Fusce sed lacinia libero, a luctus ligula. Integer in felis ex. Nam sed pellentesque tellus, in luctus nibh.',
        time: '2017-10-27T16:39:32+00:00',
        importance: 'Low',
        read: false
    },
    {
        title: 'Notification Two',
        description: 'Donec quis ligula odio. Sed sit amet magna eu erat posuere maximus. Nulla vitae erat pharetra, molestie augue in, pellentesque urna. Nullam gravida, turpis ac imperdiet cursus, elit lorem facilisis est, nec posuere magna arcu sed metus. Cras a ex ultrices, sagittis quam sit amet, sollicitudin massa. Nam orci turpis, sagittis ut sapien vel, mattis sodales lectus. Phasellus malesuada commodo metus, eget tempus nibh consectetur ac. Nullam dictum dui ac nunc accumsan, tristique varius risus porta. Mauris velit diam, cursus eu enim sit amet, egestas suscipit augue.',
        importance: 'High',
        time: '2017-11-28T12:38:34+00:00',
        read: false
    },
    {
        title: 'Notification Three',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-11-29T09:56:43+00:00',
        read: false
    },
    {
        title: 'Notification Four',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-12-04T12:38:34+00:00',
        read: true
    },
    {
        title: 'Notification Five',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-11-27T16:39:32+00:00',
        read: false
    },
    {
        title: 'Notification Six',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'High',
        time: '2018-01-04T12:38:34+00:00',
        read: false
    },
    {
        title: 'Notification Seven',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-11-27T16:39:32+00:00',
        read: false
    },
    {
        title: 'Notification Eight',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'High',
        time: '2017-11-27T13:38:34+00:00',
        read: true
    },
    {
        title: 'Notification Nine',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-11-28T13:38:34+00:00',
        read: false
    },
    {
        title: 'Notification Ten',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2016-07-11T12:11:20+00:00',
        read: true
    },
    {
        title: 'Notification Eleven',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-10-21T09:36:37+00:00',
        read: false
    },
    {
        title: 'Notification Twelve',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'High',
        time: '2017-01-01T01:11:10+00:00',
        read: true
    },
    {
        title: 'Notification Thirteen',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2016-06-16T06:35:22+00:00',
        read: false
    },
    {
        title: 'Notification Fourteen',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'High',
        time: '2017-05-27T16:39:32+00:00',
        read: false
    },
    {
        title: 'Notification Fifteen',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-08-19T19:12:00+00:00',
        read: false
    },
    {
        title: 'Notification Sixteen',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-09-28T18:56:22+00:00',
        read: true
    },
    {
        title: 'Notification Seventeen',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-07-07T07:11:49+00:00',
        read: false
    },
    {
        title: 'Notification Eighteen',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'High',
        time: '2016-02-27T09:11:32+00:00',
        read: true
    },
    {
        title: 'Notification Nineteen',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'Low',
        time: '2017-11-13T13:14:55+00:00',
        read: false
    },
    {
        title: 'Notification Twenty',
        description: 'Praesent varius metus et efficitur sollicitudin. Mauris diam neque, feugiat vitae lorem non, accumsan lacinia urna. Morbi faucibus enim ut eros ullamcorper, ultricies malesuada massa ultrices. Vivamus rutrum urna purus, sed blandit ipsum finibus sed. In molestie diam ut justo convallis maximus. Nulla massa arcu, molestie et mauris eu, semper sodales magna. Nunc faucibus iaculis dictum. Nulla feugiat, est lobortis scelerisque pellentesque, est enim rutrum nulla, non laoreet orci ligula quis ex.',
        importance: 'High',
        time: '2017-09-27T06:43:32+00:00',
        read: false
    }
]

this.shownNotifications = this.notifications;

-

Directive:

app.directive('clearNotifications', function($mdDialog, $mdToast, $timeout) {
return {
    restrict: 'A',
    controller: 'notificationsController', 
    controllerAs: 'notifications',
    scope: false,
    bindToController: true,
    link: function($scope, element, attrs, callback) {
        element.bind('click', function() {

            var notifications = $scope.notifications;

            notifications.notifications.length = 0;
            console.log(notifications.notifications);

            console.log('notifications.test: ' + notifications.test);

            /* Show confirmation prompt dialog */
            var confirm = $mdDialog.confirm()
                .parent(angular.element('body'))
                .clickOutsideToClose(true)
                .title('Are you sure you want to clear all notifications?')
                .textContent('This action cannot be undone.')
                .ariaLabel('Confirm notifications list clearance')
                .ok('Yes')
                .cancel('No')
                .targetEvent(element)


            /* On confirm */
            $mdDialog.show(confirm).then(function() {
                $scope.status = 'All notifications deleted';
                console.log($scope.status);

                /* Show notifications list loader */
                $scope.showLoader = true;
                $timeout(function() {
                    $scope.showLoader = false;
                }, 1000)


                /* Clear notifications array */
                notifications.notifications.length = 0;
                notifications.shownNotifications.length = 0;
                console.log(notifications.notifications);
                notifications.shownNotifications = angular.copy(notifications.notifications);
                console.log(notifications.shownNotifications);
                $scope.noNotifications = true;


                /* Reset filters to 'All' default */
                notifications.filters = angular.copy(notifications.resetFilters);


                /* Show toast */
                //$scope.toastTitle = 'TEST';
                $mdToast.show(
                    $mdToast.simple()
                        .content('All notifications cleared')
                        .action('Close')
                        .position('bottom right')
                        .hideDelay(500000)
                )

                notifications.callback();
            }, 

                /* On cancel */
                function() {
                $scope.status = 'Notifications clearance cancelled';
                console.log($scope.status);
            })
        })
    }
}
})
1
  • When asking a question about a problem caused by your code, you will get much better answers if you provide code people can use to reproduce the problem. That code should be… Minimal – Use as little code as possible that still produces the same problem. See How to create a Minimal, Complete, and Verifiable example. Commented Dec 14, 2017 at 16:48

1 Answer 1

0

Base on jsFiddle. The problem is that you are connecting the same controller twice: to template with the list

<div ng-controller="mainController as main">

and in the directive

controller: 'mainController',

Controller is a constructor - it means that connecting it by ngController and 'clearItems' directive you are creating two instances. From that reason when you change data in one directive, it will not be reflected on second.

Suggested solution would be:

  1. disconnect notificationsController controller from clearNotifications directive
  2. create a function that clears the items list in the notificationsController
  3. pass this function to clearNotifications directive
  4. parse/call clearNotifications directive connected function when button in dialog will be clicked

    app.controller('notificationsController', function($scope) {
    
        // ...
    
        main.clearNotifications = function() {
          this.shownNotifications.length = 0;
        };
    })
    
    app.directive('clearNotifications', ['$parse', function($parse) {
        return {
        restrict: 'A',
        scope: {},
        link: function($scope, element, attrs) {
    
          var clearNotificationsFn = dropFn = $parse(attrs.clearNotifications);
          // ...
          $mdDialog.show(confirm).then(function() {
            // ...
            clearNotificationsFn($scope, {$event:event});
          });
    
        }
      }
    }]);
    

Then in your HTML you can connect this directive to button or what ever that triggers clearing notifications list e.g.

<button clear-notifications="ctrl.clearNotifications()">
  Clear notifications
</button>
Sign up to request clarification or add additional context in comments.

3 Comments

Sorry, I forgot to place it in directive injector. $parse is an angular service, you should inject it the module definition: `app.directive('clearNotifications', ['$parse', function($parse) {...}]);
$event also can't be used in the directive because it's not injected anywhere, and wouldn't be of any use to this if it was
The code given is not end solution, but helper to better describe solution. You don't need to pass any $event, but my intention here was to pass forward element.click event.

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.