É correto passar a "corrente" $scope
para um serviço AngularJS?
Estou em uma situação em que tenho um $ serviço sabendo que é consumido por apenas um controlador e gostaria de ter uma referência ao escopo do controlador nos próprios métodos de $ serviço.
Isso é filosoficamente correto?
Ou é melhor transmitir eventos para $ rootScope e depois fazer meu controlador ouvi-los?
$scope
propriedades e ligar$scope.$apply
quando necessário.$scope
... como o controlador acessaria diretamente os dados no serviço e os passaria para a visualização sem fazer isso?Respostas:
Para permitir que o controlador saiba quando algo assíncrono acontece, use promessas angulares .
Para provocar o
$apply
, você não precisa do escopo, você pode chamar$rootScope.$apply
, pois não há diferença chamá-lo em um escopo específico ou na raiz.Em relação à leitura da variável, seria melhor se você recebesse parâmetros. Mas você também pode lê-lo de um escopo como um parâmetro de objeto, mas eu escolheria o parâmetro, que tornaria sua interface de serviço muito mais clara.
fonte
$scope
através de uma chamada para um serviço usando umaexecuteSql()
função assíncrona . Olhando para 3 opções (1) usar um retorno de chamada na função assíncrona, então chamar$scope.$apply
... isso funciona, mas é feio (2) passar$scope
para a função assíncrona, então chamartheScope.$apply()
... isso também funciona (3) usar uma promessa. ..não tentei isso ainda. Por que uma promessa é a melhor maneira? Obrigado!Eu diria que se sua funcionalidade é específica para apenas um controlador, você não precisa de um serviço.
As tarefas dos controladores são manipular o modelo específico, enquanto um serviço deve lidar com tarefas globais. Prefiro seguir esse paradigma em vez de confundir as coisas.
Isso é o que os documentos dizem
Serviço
Controlador
PS: Além disso, se você precisar digerir, você também pode injetar o $ rootScope no seu serviço.
fonte
$apply
ou$digest
para o $ rootScope faz todo o sentido para mim.Sim. Você pode passar o $ escopo para o serviço ao inicializá-lo. No construtor de serviço, você pode atribuir o escopo a algo como this._scope e então referenciar o escopo dentro do serviço!
fonte
$scope
sempre que aquele determinado controlador injetar o serviço - para não ter que chamar um método no serviço e passar manualmente$scope
para ele.new MyFunction()
). A pergunta era sobre um serviço, onde ligarnew
não é uma opção.Pessoalmente, acredito que passar
$scope
para um serviço é uma má ideia , porque cria uma referência meio circular: o controlador depende do serviço e o serviço depende do escopo do controlador.Além de confundir as relações, coisas como essa acabam atrapalhando o catador de lixo.
Minha abordagem preferida é colocar um objeto de domínio no escopo do controlador e passá-lo para o serviço. Desta forma, o serviço funciona independentemente de ser usado dentro de um controlador ou talvez dentro de outro serviço no futuro.
Por exemplo, se o serviço deve enviar e remover elementos de uma matriz
errors
, meu código será:O serviço interage então com o controlador operando em
errors
. É claro que tenho que ser cauteloso em nunca apagar a referência de array inteira, mas no final do dia essa é uma preocupação geral de JS.Eu nunca gostaria de usar transmissão,
$apply
e / ou coisas semelhantes, porque em mim, as boas práticas OO sempre superarão qualquer magia Angular.fonte
$scope.errors = []; $scope.myService = new MyService($scope.errors);
errors
vive independentemente de$scope
. Esse é o ponto principal desta resposta. Por favor, verifique o link que forneci no texto. Felicidades.$scope.errors
está apontando paravar errors
, e os erros de variável parecem redundantes para mim, pois é apenas outro ponteiro. Uma situação semelhante que eu posso pensar e que é descaradamente redundante é este pedaço de código:const errors = errors2 = errors3 = []; $scope.errors = errors;
. Você concorda que apenas com a parte do código que você forneceu parecevar errors = []
redundante?errors
vive independentemente de$scope
. Você precisa entender o que é um objeto de domínio, bem como o que é umavar
atribuição. Se o link que forneci não for suficiente, há muitos outros materiais disponíveis.MyService(errors)
. No meu entendimento, o serviço deve gerar uma matriz de registro com base no parâmetro (neste caso, um ponteiro). Para mim, esse é um padrão ruim, pois os serviços são singletons no angular. Se a implementação do serviço estiver bem programada, deve-se gerar o array em uma variável interna (para continuar sendo um singleton). Portanto, não faz sentido inicializar a variável fora do serviço.