Estou tendo um pouco de dificuldade para entender a injeção de dependência em angular. Então, minha pergunta é: alguém pode explicar quais dos "tipos", como Controller, Factory, Provider, etc, podemos injetar em outros, incluindo outras instâncias do mesmo "tipo"?
Na verdade, o que estou procurando é esta tabela preenchida com y / n. Para células com a mesma linha / coluna, isso significa injetar o valor de um "tipo" em outro com o mesmo "tipo"
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
| Can we inject? | Constant | Controller | Directive | Factory | Filter | Provider | Service | Value |
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
| Constant | | | | | | | | |
| Controller | | | | | | | | |
| Directive | | | | | | | | |
| Factory | | | | | | | | |
| Filter | | | | | | | | |
| Provider | | | | | | | | |
| Service | | | | | | | | |
| Value | | | | | | | | |
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
angularjs
dependency-injection
user1527166
fonte
fonte
Respostas:
Em vez disso, basta preencher a tabela com "sim" e "não" sem explicação, irei detalhar um pouco mais.
[Nota, adicionada após o término: isso acabou sendo ... um pouco mais longo do que eu esperava. Há um tl; dr na parte inferior, mas espero que isso seja informativo.]
[Esta resposta também foi adicionada ao wiki do AngularJS: Entendendo a injeção de dependência ]
O Fornecedor (
$provide
)O
$provide
serviço é responsável por informar à Angular como criar novas coisas injetáveis; essas coisas são chamadas de serviços . Os serviços são definidos por coisas chamadas provedores , que é o que você cria quando usa$provide
. A definição de um provedor é feita peloprovider
método no$provide
serviço, e você pode se apossar do$provide
serviço solicitando que ele seja injetado naconfig
função de um aplicativo . Um exemplo pode ser algo como isto:Aqui nós definimos um novo provedor para um serviço chamado
greeting
; podemos injetar uma variável nomeadagreeting
em qualquer função injetável (como controladores, mais sobre isso posteriormente) e o Angular chamará a$get
função do provedor para retornar uma nova instância do serviço. Nesse caso, o que será injetado é uma função que recebe umname
parâmetro e umaalert
mensagem com base no nome. Podemos usá-lo assim:Agora, aqui está o truque.
factory
,,service
evalue
todos são apenas atalhos para definir várias partes de um provedor - ou seja, eles fornecem um meio de definir um provedor sem precisar digitar tudo isso. Por exemplo, você pode escrever exatamente o mesmo provedor da seguinte maneira:É importante entender, então vou reformular: sob o capô, o AngularJS está chamando exatamente o mesmo código que escrevemos acima (a
$provide.provider
versão) para nós. Não há, literalmente, 100% de diferença nas duas versões.value
funciona da mesma maneira - se o que quer que retornássemos da nossa$get
função (também conhecida como nossafactory
função) é sempre exatamente o mesmo, podemos escrever ainda menos código usandovalue
. Por exemplo, como sempre retornamos a mesma função para nossogreeting
serviço, também podemosvalue
defini-la:Novamente, isso é 100% idêntico aos outros dois métodos que usamos para definir essa função - é apenas uma maneira de salvar algumas digitações.
Agora você provavelmente notou essa
app.config(function($provide) { ... })
coisa chata que tenho usado. Como definir novos provedores (através de qualquer um dos métodos acima) é tão comum, o AngularJS expõe os$provider
métodos diretamente no objeto do módulo, para economizar ainda mais digitação:Todos eles fazem o mesmo que as
app.config(...)
versões mais detalhadas que usamos anteriormente.O injetável que pulei até agora é
constant
. Por enquanto, é fácil dizer que funciona da mesma maneiravalue
. Veremos que há uma diferença mais tarde.Para revisar , todos esses trechos de código estão fazendo exatamente a mesma coisa:
O Injetor (
$injector
)O injetor é responsável por realmente criar instâncias de nossos serviços usando o código que fornecemos via
$provide
(sem trocadilhos). Sempre que você escreve uma função que recebe argumentos injetados, vê o injetor funcionando. Cada aplicativo AngularJS possui um$injector
que é criado quando o aplicativo é iniciado pela primeira vez; você pode controlá-lo injetando$injector
qualquer função injetável (sim,$injector
sabe como se injetar!)Depois de ter
$injector
, você pode obter uma instância de um serviço definido chamandoget
-o com o nome do serviço. Por exemplo,O injetor também é responsável por injetar serviços nas funções; por exemplo, você pode injetar serviços magicamente em qualquer função que tenha usando o
invoke
método do injetor ;Vale a pena notar que o injetor criará apenas uma instância de um serviço uma vez . Em seguida, ele armazena em cache o que o provedor retornar pelo nome do serviço; Na próxima vez em que você solicitar o serviço, você obterá exatamente o mesmo objeto.
Portanto, para responder sua pergunta, você pode injetar serviços em qualquer função chamada
$injector.invoke
. Isso inclui$get
métodos dos provedores (também conhecidos comofactory
funções de definição)Como
constant
s evalue
s sempre retornam um valor estático, eles não são invocados pelo injetor e, portanto, você não pode injetá-los com nada.Configurando Provedores
Você pode estar se perguntando por que alguém iria incomodar a criação de um provedor de pleno direito com o
provide
método sefactory
,value
, etc, são muito mais fácil. A resposta é que os provedores permitem muita configuração. Já mencionamos que, ao criar um serviço por meio do provedor (ou qualquer um dos atalhos fornecidos pelo Angular), você cria um novo provedor que define como esse serviço é construído. O que eu não mencionei é que esses provedores podem ser injetados emconfig
seções do seu aplicativo para que você possa interagir com eles!Primeiro, o Angular executa seu aplicativo em duas fases - as fases
config
erun
. Aconfig
fase, como vimos, é onde você pode configurar qualquer provedor, conforme necessário. É também aqui que diretivas, controladores, filtros e similares são configurados. Arun
fase, como você pode imaginar, é onde o Angular realmente compila seu DOM e inicia seu aplicativo.Você pode adicionar código adicional a ser executado nessas fases com as funções
myMod.config
emyMod.run
- cada uma delas executa uma função para executar durante essa fase específica. Como vimos na primeira seção, essas funções são injetáveis - injetamos o$provide
serviço interno em nosso primeiro exemplo de código. No entanto, o que vale a pena notar é que, durante aconfig
fase, apenas os provedores podem ser injetados (com exceção dos serviços noAUTO
módulo--$provide
e$injector
).Por exemplo, o seguinte não é permitido :
O que você faz tem acesso a quaisquer provedores de serviços que você fez:
Há uma exceção importante:
constant
s, uma vez que não podem ser alterados, podem ser injetados dentro deconfig
blocos (é assim que diferem devalue
s). Eles são acessados apenas pelo nome (não éProvider
necessário sufixo).Sempre que você define um provedor para um serviço, esse provedor é nomeado
serviceProvider
, ondeservice
é o nome do serviço. Agora podemos usar o poder dos provedores para fazer coisas mais complicadas!Agora, temos uma função em nosso provedor chamada
setText
que podemos usar para personalizar nossaalert
; podemos obter acesso a esse provedor em umconfig
bloco para chamar esse método e personalizar o serviço. Quando finalmente executamos nosso aplicativo, podemos pegar ogreeting
serviço e testá-lo para ver se nossa personalização entrou em vigor.Como este é um exemplo mais complexo, aqui está uma demonstração de trabalho: http://jsfiddle.net/BinaryMuse/9GjYg/
Controladores (
$controller
)As funções do controlador podem ser injetadas, mas os próprios controladores não podem ser injetados em outras coisas. Isso ocorre porque os controladores não são criados por meio do provedor. Em vez disso, existe um serviço Angular interno chamado
$controller
responsável pela configuração de seus controladores. Quando você ligamyMod.controller(...)
, está realmente acessando o provedor deste serviço , assim como na última seção.Por exemplo, quando você define um controlador como este:
O que você está realmente fazendo é o seguinte:
Posteriormente, quando o Angular precisar criar uma instância do seu controlador, ele usará o
$controller
serviço (que por sua vez usa o$injector
para chamar a função do controlador para que também seja injetada suas dependências).Filtros e Diretivas
filter
edirective
funciona exatamente da mesma maneira quecontroller
;filter
usa um serviço chamado$filter
e seu provedor$filterProvider
, enquantodirective
usa um serviço chamado$compile
e seu provedor$compileProvider
. Alguns links:Conforme os outros exemplos,
myMod.filter
emyMod.directive
são atalhos para configurar esses serviços.Portanto, para resumir, qualquer função que seja chamada
$injector.invoke
pode ser injetada . Isso inclui, no seu gráfico (mas não se limita a):$get
(ao definir provedor como um objeto)O provedor cria novos serviços que podem ser injetados nas coisas . Isso inclui:
Dito isto, serviços internos gostam
$controller
e$filter
podem ser injetados, e você pode usá- los para se apossar dos novos filtros e controladores que você definiu com esses métodos (mesmo que as coisas que você definiu não possam, por si só, ser injetado nas coisas).Para além de que, qualquer função invocada-injector pode ser injectado com qualquer serviço fornecido pelo provedor - não há nenhuma restrição (excepto o
config
erun
diferenças aqui listados).fonte
O ponto que a BinaryMuse faz em sua resposta incrível sobre fornecedores, fábricas e serviços é a mesma coisa extremamente importante.
Abaixo está uma imagem que acho que pode ilustrar visualmente o argumento dela:
(fonte: simplygoodcode.com )
fonte
Ótima resposta de Michelle. Eu só quero ressaltar que diretivas podem ser injetadas. Se você tiver uma diretiva denominada
myThing
, poderá injetá-la commyThingDirective
: Aqui está um exemplo artificial .O exemplo acima não é muito prático, no entanto, a capacidade de injetar uma diretiva é útil quando você deseja decorá-la .
fonte