Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Serviço ou rootScope?

Amigos,

Criei um serviço só armazenar constantes importantes do meu projeto. Um exemplo é o endereço do meu servidor, pois quando estou usando localmente aponto esse end para localhost, quando faço upload para o meu servidor coloco o endereço da internet.

O problema é que fica chato eu injetar a todo momento esse serviço em cada controller para disponibilizar para o Html essas métodos.

Pensei em colocar no rootScope, porém o rootScope não consegue acessar os métodos do meu serviço. E se eu mudar a abordagem e colocar esses métodos direto no rootScope, vou ter que injetar no serviço o rootScope, o que deixa meu serviço totalmente acoplado ao rootScope, o que eu não gostaria.

Qual seria a melhor abordagem para esse caso?

6 respostas

Usar $rootScope não é uma boa prática. Tudo que você colocar nele estará disponível em todo lugar da sua aplicação. E como se fosse um escopo Global, mas do Angular. (e sabemos como programadores os problemas do escopo Global. .principalmente quem trabalha com js todos os dias).

Já um serviço, ele só estará disponível onde você injeta-lo. Isso é perfeito porque isola seu código e responsabilidades bem definidas.

A questão aqui nem é tanto de Angular, mas sobre Boas práticas de desenvolvimento.

Flávio,

Então nesse caso, vou ter que injetar esse serviço em todos os meus controles e criar uma varíavel para receber essa informação do serviço, para depois ai sim conseguir utilizar no HTML? Não achei uma boa solução.

Eu tenho como acessar o serviço diretamente no html? Já ficaria melhor do que ficar criando no Controller a todo momento um uma $scope.enderecoBase = meuServico.enderecoServidor();

Não tem como acessar um Serviço diretamente no HTML. O que você pode é injetar um serviço em um controller e associar alguma ação do controller à alguma chamada no serviço (algo como você mostrou).

Isso foi uma decisão de design da equipe do Angular. Só podemos disponibilizar uma informação para a view através de $scope ou $rootScope. Porém, o uso de $rootScope é desencorajado, por isso deixou de existir em Angular 2 (que ainda não saiu a versão final).

Eduardo, eu entendo sua preocupação: você quer escrever menos e o Angular está te obrigando a escrever mais. Mais nem sempre escrever mais código é ruim, principalmente neste caso.

Em um projeto grande em Angular, quando abro um módulo ou um controller, eu sei justamente o que ele faz porque ele tem que ter uma responsabilidade bem definida, além disso, sei logo de cara todas as suas dependências. Sei tudo aquilo que é necessário para aquele código funcionar (logo na primeira linha).

Se você tasca tudo em $rootScope, eu já não consigo ver com clareza no seu código quais são as dependências para aquele código funcionar, vejo apenas a injeção de $rootScope. Mas o que queremos dele? Tem tanta coisa lá! Ai começa a manutenção e legibilidade do seu código ficar comprometida.

Uma analogía pode ajudá-lo. Imagine que você precise de um forno para esquentar sua comida. Injetamos o forno dentro de um módulo. Quem quiser esquentar comida, injetada aquele forno. Se dar um problema, basta consertar o forno.

Agora, imagine que alguém, além de precisar de um forno precise de uma batedeira, mas nem todos precisam de uma batedeira. Perfeito, em um módulo injeto forno e batedeira e quem precisa só de forno eu injeto forno. Daí, deu um problema na batedeira. Afetará quem em meu sistema? Só quem depende de batedeira, porque quem depende só de forno não é afetado.

Colocar as coisas no $rootScope é fazer com que ele seja um FornoBatedeira. Se um controller precisa apenas do forno, ele receberá um FornoBatedeira. Até ai tudo bem, porque ele vai conseguir usar o forno mesmo sem ter interesse em usar a batedeira. Agora, e se dá pau no motor da batedeira? Tudo estará com problema e mesmo aqueles que só dependem do forno, ficarão sem forno só porque deu problema na batedeira. Forma clássica de gerar bugs e problema de manutenção em sistemas.

Espero ter ajudado.

Flavio,

Exatamente o que você falou, gostaria de escrever menos rs. Mas tudo bem, vou seguir o que você orientou.

Uma outra situação, tenho uma tela de loading, que é um modal que ocupa a tela toda e coloca um Carregando ...

Essa DIV não posso colocar dentro do ng-view, pois quero que ela esteja disponível em qualquer tela a qualquer momento.

O problema volta para o rootScope rs. Eu tenho nela um ng-show, que é uma variável definida a nível de rootScope, justamente para qualquer Controller, dependendo do que for fazer, poder ativar ou não essa tela. Ai eu te pergunto, se no AngularJS 2 não existir mais o rootScope, como resolveria esse problema que é tão cotidiano?

Não estou querendo ser chato, é que estou usando o angular em um projeto e estou esbarrando nesses pontos.

solução!

Isso é outra dúvida, conclua esse post (que aliás, já está concluído) e crie um novo post.

Sobre isso, ajudei um aluno brilhante há pouco tempo com um problema parecido. Você pode dar uma fuçada na solução dele.

https://www.alura.com.br/course/angularjs-mvc/discussions/673506

Outra coisa é fazer parte do fórum do Angular.js Brasil do facebook, isso vai acelerar a resolução dos seus problemas.

Bom estudo.