0

What is happening here is some menu items are enabled and some are disabled in the ui. So when user clicks on a menu item which is disabled it gives an error on the page.

I tried to solve the issue using angularjs-service and $broadcast. Now the thing is since every page including the left menu has different controllers so i needed to repeat the $broadcast data to every controller. All I am looking forward to is how can I remove this redundancy?

Left-Menu-Service.js

'use strict';
angular.module("MainApp")
.factory('menuClick', function($rootScope) {
    var sharedService = {};
    sharedService.notify = {};

    sharedService.prepForBroadcast = function(msg) {
        this.broadcastItem();
    };
    sharedService.broadcastItem = function() {
        $rootScope.$broadcast('handleBroadcast');
    };
    return sharedService;
});

Left-Menu-Controller.js

 'use strict';
  angular.module("MainApp")
.controller('LeftMenuCtrl', function ($scope, $rootScope, menuClick) {
        $scope.handleMenuClick = function(action) {
        menuClick.notify.warningNotify =  true;
        menuClick.notify.errorNotify =  true;
        menuClick.notify.successNotify =  true;

        if(!action.IsEnabled)
        {
            menuClick.notify.warningNotify = false;
            menuClick.notify.warningMessage = "This operation is disabled ( "+action.Text+" )";
            menuClick.prepForBroadcast(menuClick.notify);
        }
    };

});

Left-Menu.html

<li>
    <a ng-click="handleMenuClick(submenu)">{{submenu.Text}}</a>
</li>

Notification-Directive.js

'use strict';
angular.module("MainApp")
.directive('notification', function () {
    return {
        restrict: 'E',
        templateUrl: function (tElement, tAttrs) {
            if (tAttrs.type) {
                switch (tAttrs.type){
                    case 'error':
                        return 'partials/template/show_error.html';
                        break;
                    case 'success':
                        return 'partials/template/show_success.html';
                        break;
                    case 'warning':
                        return 'partials/template/show_warning.html';
                        break;
                }
            }
        }

    };
});

show_error.html

<div ng-hide="notify.errorNotify" ng-init="notify.errorNotify=true">

    <button type="button" ng-click="notify.errorNotify = !notify.errorNotify"></button>
    <h2>{{notify.errorMessage}}</h2>

</div>

Controller-of-the-all-the-pages-where-this-directive-is-used.js

$scope.$on('handleBroadcast', function() {
        $scope.notify = menuClick.notify;
});

I don't know how patch the whole stuff in the directive itself so that repetition of the above code in all the controllers could be avoided. Thanks!

4
  • 1
    I'm not sure I fully understand your question but I see you're making separate modules for each part of your app :) great to see more people doing this. I have an example that I put together here. Look into app/shared/navigation-bar. Here you will find a directive that I built to add the navbar and controler . Hope this helps Commented Sep 19, 2015 at 12:12
  • @JoeLloyd there's only one module in OP code, not sure what you mean by separate modules Commented Sep 19, 2015 at 12:20
  • @charlietfl ah I just read his module name, I was distracted. My bad. But take a look at my example anyway you can see a directive and how features become modules. Commented Sep 19, 2015 at 12:22
  • @JoeLloyd fully understand using modules for features but it's not really relevant to OP's situation Commented Sep 19, 2015 at 12:28

1 Answer 1

1

This may not be the ideal answer but will help you understand how to use service to share methods.

Move the function declaration for $scope.handleMenuClick from controller to your service:

.factory('menuClick', function($rootScope) {
    var sharedService = {};
    sharedService.notify = {};
     // new function 
     sharedService.handleMenuClick = function(action) {
        sharedService.notify.warningNotify =  true;
        .......
        if(!action.IsEnabled)
        .......
     }
     .....
     return sharedService 
})

Then in controller you only need a reference to the method in service:

$scope.handleMenuClick = menuClick.handleMenuClick; 
Sign up to request clarification or add additional context in comments.

4 Comments

ThankYou but you still needs to repeat $scope.handleMenuClick = menuClick.handleMenuClick; to every controller don't you?
not necessarily if menu is put into directive or simply uses it's own controller. We don't know how you have your views set up
Well yes for both. Menu has been put into a directive and has it'e own controller.
Also note that you don't have to copy every property of service object to controller but can still use properties in view

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.