How to create the service of a controller?

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 just create services for things that will be duplicated in the code and related or 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;
    };
});
    
asked by anonymous 26.10.2015 / 05:53

3 answers

7
  

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

Yes, it is possible. Actually, the way your controller was written, conversion to a service becomes very simple. You only need to consider a few things:

Services do not have $ scope

Angled services are singletons - meaning that only one instance is created. Since $scope is an Angular tool to reference the context of each instance, it is unnecessary. In this case, you need to convert all mentions from $scope to this .

References to this in functions need to be reviewed

One more 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><divng-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>

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

    
26.10.2015 / 14:10
6

What is an angled service?

An angled service is for sharing resources between controllers. The most common use in this case is the use of this feature to create a common http communication interface. For example, you can have a service called person and use that on different controllers. This service will provide a data access interface for the entire application as it pertains to a person (see, edit, include, and so on).

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 service $ person and $ sale. The person service is shared between two controllers, PersonController and SaleController. The idea of the service is just that. Share common interfaces between controllers.

Is it possible to use a driver to encapsulate common methods?

Yes! It is possible, though I do not recommend it. A service has some limitations that can give more headache 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");
    }
    };
}]);

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

    
26.10.2015 / 12:27
3

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

In general, services provide access to features or functionality shared by the entire application, examples of which are, server-side calls, user information, and the like.

Controllers are structures to control behaviors on 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 creating a service: link but the best posts about the subject is in English, if you want more information the "angular service" search should give you satisfactory results.

    
26.10.2015 / 12:12