AngularJS Informer service

非 Y 不嫁゛ 提交于 2019-12-04 08:57:50

In AngularJS we should be focusing on model manipulation and your Informer service is no exception - it should only hold model and shouldn't be concerned with DOM manipulation. The rule of thumb where DOM manipulation = directive is a very good one and if you follow it it will save you a lot of headaches.

Back to your problem at hand, the solution is to have a service focused on model manipulation and a directive to display this model. Let's start with the service:

app.factory('Informer', function(){

  var messages = [];  
  var Informer = {};

  Informer.inform = function(msg, type) {
    messages.push({
      msg: msg,
      type: type
    });
  };

  Informer.allInfos = function() {
    return messages;
  };

  Informer.remove = function(info) {
    messages.splice(messages.indexOf(info), 1);
  };  

  return Informer;
});

When this service is ready you can easily use it in a controller (or even inside other services!):

app.controller('MainCtrl', function($scope, Informer) {

  Informer.inform("error message", "error");
  Informer.inform("info message", "info");

  $scope.allInfos = Informer.allInfos;  
  $scope.remove = Informer.remove;
});

And finally, to render alerts you can use bootstrap's markup directly, or write a very simple directive that encapsulates it. Here I', using the alert directive from http://angular-ui.github.com/bootstrap/

<body ng-controller="MainCtrl">
    <alert ng-repeat="alert in allInfos()" type="alert.type" close="remove(alert)">{{alert.msg}}</alert>
  </body>

Of course you don't need to use directives from this repo, you can create your own or use raw markup if needed.

Here is a plunker demonstrating a working example: http://plnkr.co/edit/VxAcjHFhxXODFB5iAfyX?p=preview

To sum up:

  • As a rule of thumb don't do DOM manipulation outside of directives
  • Service dealing with the model should be decoupled from model's presentation

I would also advice removing jQuery from a project while learning AngularJS. This way you will quicker get into AngularJS-zen state!

Angular way, I believe, is to manipulate dom by hand as few as possible. And even if you have to manipulate it - do it only within a directive.

So, the way to go, unlike jQuery, is to have a model and use bindings to change your dom.

For that reason, the way I would choose - it to have some InformerController which is binded somewhere in your layout template, and iterate over an array of current informs, and draw them directly.

app.controller('InformersController', function($scope, InformerService) {
    $scope.informs = InformerService.get();
    $scope.close = function (index) {
          InformerService.close(index)
    }
});

And in your template:

<div ng-controller="InformersController">
     <div ng-repeat="inform in informs">
         <div class="alert {{inform.alertClass}} fade in informer">
            <button type="button" ng-click="close($index)" class="close">×</button>
            <div class="valignCenterWrapper">
                <div class="valignCenter">
                    {{inform.message}}
                </div>
            </div>
        </div>
     </div>
 </div>

If you need to show some alert from any place, use it injecting InformerService to your controller, and adding data using it.

app.service('InformerService', function () {

    var informs = [];
    this.get = function () {
        return informs;   
    };
    this.inform = function (message, type) {
        informs.push({
            alertClass: 'alert-' + type,
            message: message
        });
    }
    this.close = function (index) {
       informs.splice(index, 1);
    }

});

For example:

app.controller('SomeController', function($scope, InformerService) {
    $scope.doError = function (msg, type) {
        InformerService.inform(msg, type);
    };
});

And in your template:

<div class="well" ng-controller="SomeController">
    <button class="btn btn-danger" ng-click="doError('Hello', 'error')">Error</button>  
    <button class="btn btn-info" ng-click="doError('Hello', 'info')">Info</button>  
</div>

You can see it all together at this fiddle: http://jsfiddle.net/zc3YH/6/

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