How to create a controller service?

Asked

Viewed 2,015 times

6

Hello, I would like to know if it is possible with this code to create a service. Because all the videos I see they only create services for things that will be duplicated in code and so on or from localhost links. If you can help me, thank you.

angular.module('TarefApp')

.controller('TarefasController', function($scope) {
    $scope.categorias = [
        {nome:'Tarefas Primárias'},
        {nome:'Tarefas Secundárias'},
    ];
    $scope.tarefas = [];
    $scope.categoriaTarefa = {tarefa:{}};     

    $scope.addTarefa = function(tarefa) {
        if(!$scope.categoriaSelecionada){
            alert("Selecione uma categoria!")
            return;
        }

        var c = $scope.categoriaSelecionada;

        if(!$scope.categoriaTarefa.tarefa[c])
        $scope.categoriaTarefa.tarefa[c] = [];
        else{
            var itemDuplicado = false;
            angular.forEach($scope.categoriaTarefa.tarefa[c], function (item, index){
                itemDuplicado = (item.nome === tarefa.nome);
                if(itemDuplicado){
                    alert("Tarefa para categoria já existe!");
                    return false;
                }
            });
        }

        if(!itemDuplicado){
            $scope.categoriaTarefa.tarefa[c].push(tarefa);
            $scope.tarefa = {};
        }
    };

    $scope.delTarefas = function() {
        angular.forEach($scope.categorias, function(item) {
            var c = item.nome;
            var oldTarefas = $scope.categoriaTarefa.tarefa[c];
            $scope.categoriaTarefa.tarefa[c] = [];

            angular.forEach(oldTarefas, function(tar) {
                if (!tar.selecionado) $scope.categoriaTarefa.tarefa[c].push(tar);
            });
        });
    };

    $scope.addCategoria = function(categoria) {
        for(var i=0; i < $scope.categorias.length; i++){
            if($scope.categorias[i].nome === categoria.nome){
                alert("A categoria já existe!");
                return;
            }
        }
        $scope.categorias.push(angular.copy(categoria));
        delete $scope.categoria;
    };
});

3 answers

7


[...]it is possible with this code to create a service[?].

Yes, it is possible. In fact, the way his controller was written, the conversion to a service becomes very simple. You only need to take into consideration a few points:

Services do not have $Scope

Services in Angular are singletons - which means that only one instance is created. How $scope is an Angular tool to reference the context of each instance, it is unnecessary. In this case, you need to convert all mentions of $scope for this.

References to this in functions need to be revised

An additional point you need to keep in mind is that javascript will create a scope for each function call, and this always points to the current context.

The solution is to create a reference to the main scope (var that = this, in my example), and use this reference instead of this within a function (!that.categoriaSelecionada).

The converted version of your code comes next:

angular.module('TarefaApp', []);

angular.module('TarefaApp')
    .service('TarefasService', function() {
        var that = this;

        this.categorias = [
            {nome:'Tarefas Primárias'},
            {nome:'Tarefas Secundárias'},
        ];
        this.tarefas = [];
        this.categoriaTarefa = {tarefa:{}};     
        this.categoriaSelecionada = {};

        this.addTarefa = function(tarefa) {
            if(!that.categoriaSelecionada){
                alert("Selecione uma categoria!")
                return;
            }

            var c = that.categoriaSelecionada;

            if(!that.categoriaTarefa.tarefa[c])
            that.categoriaTarefa.tarefa[c] = [];
            else{
                var itemDuplicado = false;
                angular.forEach(that.categoriaTarefa.tarefa[c], function (item, index){
                    itemDuplicado = (item.nome === tarefa.nome);
                    if(itemDuplicado){
                        alert("Tarefa para categoria já existe!");
                        return false;
                    }
                });
            }

            if(!itemDuplicado){
                that.categoriaTarefa.tarefa[c].push(tarefa);
                that.tarefa = {};
            }
        };

        this.delTarefas = function() {
            angular.forEach(that.categorias, function(item) {
                var c = item.nome;
                var oldTarefas = that.categoriaTarefa.tarefa[c];
                that.categoriaTarefa.tarefa[c] = [];

                angular.forEach(oldTarefas, function(tar) {
                    if (!tar.selecionado) that.categoriaTarefa.tarefa[c].push(tar);
                });
            });
        };

        this.addCategoria = function(categoria) {
            for(var i=0; i < that.categorias.length; i++){
                if(that.categorias[i].nome === categoria.nome){
                    alert("A categoria já existe!");
                    return;
                }
            }
            that.categorias.push(angular.copy(categoria));
            delete that.categoria;
        };
    })
.controller('TarefasController', function($scope, TarefasService) {
  $scope.svc = TarefasService;
})
.controller('Tarefas2Controller', function($scope, TarefasService) {
  $scope.svc = TarefasService;
});
<html ng-app='TarefaApp'>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

  </head>
  <body>
    <div ng-controller="TarefasController">
      Controle 1:<br/>
      <select class="form-control" ng-model='svc.categoriaSelecionada'>
        <option ng-repeat="categoria in svc.categorias">{{categoria.nome}}</option>
      </select>
    </div>
    <div ng-controller="Tarefas2Controller">
      Controle 2:<br/>
      {{svc.categoriaSelecionada}}
      
    </div>
  </body>
</html>

Note how the selected value in Controller 1 is shared, via service, with the Controller 2.

  • I believe part of the code is missing at the end that probably makes the code work.

  • @Larissamourullo Err... thank you, you are correct; missed copying the final lines of the service. Post edited and corrected.

  • thank you very much indeed, I found it quite easy as it was done. It helped me a lot.

  • @Larissamourullo Always a pleasure! Having more questions, feel free to ask.

  • I am trying to make it work, but nothing is happening (OBS: no error occurring). I am putting this in the controller to call services: . controller('Tarefascontroller', Function($Scope, Tarefasservice) {

  • @Larissamourullo I changed the post, including an example of control consuming your service.

Show 1 more comment

6

What is an angular service?

An angular service serves to share resources between controllers. The most common use in this case is to use this feature to create a common http communication interface. For example, you can have a service called person and use this one on different controllers. This service will provide an interfac of access to data for the entire application in what refers to a person (consult, edit, include and etc).

app.controller('PessoaController', function($scope, $pessoa) {
    $scope.cadastrar = function (){
        $pessoa.cadastrar('<passa aqui dados pessoa>');
    };

    $scope.excluir = function (){
        $pessoa.cadastrar('<passa aqui id pessoa>');
    };

    $scope.consultarPorId = function (){
        $pessoa.cadastrar('<passa aqui id pessoa>');
    };
});

app.controller('VendaController', function($scope, $pessoa, $venda) {
    $scope.incluir = function (){
        $scope.consultarPorId(idPessoa).then(efetivarVenda);
    };

    $scope.efetivarVenda = function(pessoa){
        var venda = {/* Aqui monta objeto venda */};
        venda.pessoa = pessoa;
        $venda.efetivar(venda);
    };

    $scope.consultarPorId = function (){
        $pessoa.cadastrar('<passa aqui id pessoa>');
    };
}); 

In this example you can identify the $person service and the $sale. The personal service is shared between two controllers, Pessoacontroller and Vendacontroller. The idea of the service is just this. Share common interfaces between controllers.

It is possible to use a controller to encapsulate common methods?

Yes! It’s possible, but I don’t recommend it. A service has some limitations that can give you more headaches than help. As already mentioned, the service must provide a communication interface between another system or between services.

How can I create a single point of access to common functions in the system?

You create a Commons module that can provide these common methods.

var commom = angular.module("utils.commom", []);
commom.factory("$commomutils", function($http, $q, $injector) {
    return({
        fazAlgo:function(algumaCoisa){
            console.log(algumaCoisa);
        }
    });
});

var appQualquer = angular.module("AppQualquer", ["utils.commom"]);
appQualquer.controller("ControllerQualquer", function($scope, $commomutils) {
    $scope.iniciar = function() {
        $commomutils.fazAlgo("JEC não vai cair!!! Figueira freguês!!!");
    };
});

appQualquer.directive("diretiva", [function () {
    return {
        restrict : "E",
    replace : true,
    link : function(scope, element, attr) {
            angular.element(element).html("Figueira FREGUES!!! JEC Maior de SC");
    }
    };
}]);

Note the module utils. and how it is injected into Appqualquer. This way you can centralize your common methods by having access to all necessary resources.

3

This code presented by you could rather be converted into service, the issue is that what it does, is not the behavior of an angular service.

In general, services offer access to features or features shared throughout the application, examples of which are server calls, user information and things like.

Controllers, on the other hand, are structures to command the behaviors of a screen, button events, calls to services. Realize that this is just what your current controller does.

In this link you will find a simple example of service creation: http://techbusters.com.br/criar-servico-com-angularjs/ but the best posts on the subject are in English, if you want more information the search "angular service" should return you satisfactory results.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.