AngularJS: Using services in directives

99封情书 提交于 2019-12-23 12:19:31

问题


This is an angularjs app. I have a service that handles the loading of content (ajax). While the service is getting the content, a number of things throughout the app hide, later showing again (depending on the content returned). They might have the same scope, different scope, whatever. They just need to hide while content is loading, and then show when it's done. Pretty normal stuff.

Right now, I have separate controllers watching a "loading" property of the service and using regular angular directives (ng-show, ng-hide, etc.) to show/hide. But this feels like overkill. I'd prefer to write a custom "loading" directive that injects the loading service and does the watching and showing/hiding.

My question is: Is what I want to do "bad"? The controller way, I end up boilerplating a bunch of code, maybe up to like 5 or 6 times, or even more as the app grows. The custom directive way, I write it once and use an attribute where I need it. Yeah - there's a dependency on that service, but that just doesn't feel like the end of the world that some people have made me start to think I should think it is.

For what it's worth, I feel like I've heard "separation of concerns" so many times I've become paralyzed by it. It leads me to overthink everything because I want to do things the right way, but it sure doesn't feel like I'm being very productive.


回答1:


If I understood correctly, you have a bunch elements that should hidden when a particular service is loading data, and then be displayed again when the data is loaded, right?

In that case, events might be a good solution:

  • they can be global to the appliciation (which i think is what you are aksing for).
  • they allow for avoiding direct coupling between elements (also one of your concerns).

So, in your service, just broadcast events when stuff happens:

$rootScope.$broadcast('loading-data');
axajStuffOrWhatever(function() {
   $rootScope.$broadcast('data-loaded');
});

Then, wrap the show/hide behaviour in a directive that will listen to those events.

.directive('hideWhileLoadingData', function() {
  return {
    link: function(scope, el, attrs) {
      scope.$on('loading-data', function() {
        el.css('display', 'none');
      });
      scope.$on('data-ready', function() {
        el.css('display', 'block');
      });                
    }
  };  
});

Use the directive:

<div hide-while-loading-data>something</div>

The advantage of using events here, is that later on, they could be originated by a different service, or by multiple services, and the directive will not be affected by that as long as the events are the same.

For more complex behaviour, you could also parametrize the events and the directive, so different elements will react to different kind of stuff.

I've made an example of this.




回答2:


In my opinion all scopes which depend on this service should be children of one parent scope. If you have the parent scope responsible for talking with the service then any directive of any scope can access it via $parent on the $scope.



来源:https://stackoverflow.com/questions/16848314/angularjs-using-services-in-directives

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!