什么"东西"可以注入其他人Angular.js? [英] What "things" can be injected into others in Angular.js?

查看:106
本文介绍了什么"东西"可以注入其他人Angular.js?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一点很难理解的角度依赖性注入。所以我的问题是,任何人都可以解释其中的类型,如控制器,工厂,供应商等,我们才能继续注入其他人,包括相同的类型的其他实例?

什么实际上,我找的就是这台充满着Y / N。对于具有相同的行/列的单元,这意味着一类型的值注入另一个另一个具有相同的类型

<$p$p><$c$c>+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
|我们可以注入? |恒|控制器|指令|厂|过滤器|供应商|服务|值|
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
|恒| | | | | | | | |
|控制器| | | | | | | | |
|指令| | | | | | | | |
|厂| | | | | | | | |
|过滤器| | | | | | | | |
|供应商| | | | | | | | |
|服务| | | | | | | | |
|值| | | | | | | | |
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+


解决方案

而刚刚填写表是和否没有解释,我将进入多一点点的细节。

【注意事项,完成后说:这结束了......比我预期的相当长的时间。有一个TL;博士在底部,但我希望这证明信息]

[这个答案也已经加入到AngularJS维基:理解依赖注入 ]


的提供商( $提供

$提供服务负责告诉角度如何创建新的可注射的东西;这些东西被称为服务。服务是由东西叫做提供,这是当你使用 $提供你要创建的定义。定义提供通过提供商完成的 $提供服务方法,你可以得到的保持 $按要求它提供服务被注入到应用程序的配置功能。一个例子可能是这样的:

的app.config(函数($提供){
  $ provide.provider('问候',函数(){
    这一点。$ GET =功能(){
      复位功能(名称){
        警报(你好,+姓名);
      };
    };
  });
});

在这里我们定义了一个名为服务问候新的供应商;我们可以注入一个名为问候变量到任何注射功能(如控制器,后来更多)和角度将调用提供商的 $ GET ,以便返回该服务的新实例功能。在这种情况下,将被注入的东西是一个函数,它接受一个名称参数和警报 SA消息,基于名字。我们可能会使用这样的:

app.controller('MainController',函数($范围,贺卡){
  $ scope.onClick =功能(){
    问候语(福特prefect');
  };
});

现在,这里的窍门。 工厂服务都只是快捷方式来定义一个供应商的各个部分 - 也就是说,它们提供定义提供程序,而不必输入所有的东西出来的一种手段。例如,您可以编写的完全相同的提供商就像这样:

的app.config(函数($提供){
  $ provide.factory('问候​​',函数(){
    复位功能(名称){
      警报(你好,+姓名);
    };
  });
});

要了解这一点很重要,所以我会另一种方式:在引擎盖下,AngularJS呼吁在完全相同的code ,我们写的上方( $提供。供应商版本)的的我们。有从字面上看,100%,在两个版本没有什么区别。 工作只是以同样的方式 - 如果无论我们会从我们的 $ GET 函数返回(即我们的工厂功能)始终是完全一样的,我们可以用写的就更少了code。例如,因为我们总是回到我们的问候服务相同的功能,我们可以使用来定义它,太

的app.config(函数($提供){
  $ provide.value('问候',函数(名称){
    警报(你好,+姓名);
  });
});

再次,这是100%相同,我们使用定义此功能的其他两种方法 - 它只是一个方法来节省一些打字

现在你可能注意到了这恼人的的app.config(函数($提供){...})我一直在使用的东西。自定义新的供应商(通过的任何的上面给出的方法)是如此普遍,AngularJS公开 $提供商直接在模块对象方法,以节省更多的打字:

VAR myMod = angular.module('Mymodule中',[]);myMod.provider(问候语,...);
myMod.factory(问候语,...);
myMod.value(问候语,...);

这些都为做了更详细的的app.config(...)版本中,我们使用previously同样的事情。

的模式注射到目前为止,我已经跳过是。就目前而言,这是很容易的说,它的工作原理就像。我们会看到有一个区别更高版本。

要查看 所有的这些作品code的都在做的确切的同样的事情:

myMod.provider('问候',函数(){
  这一点。$ GET =功能(){
    复位功能(名称){
      警报(你好,+姓名);
    };
  };
});myMod.factory('问候​​',函数(){
  复位功能(名称){
    警报(你好,+姓名);
  };
});myMod.value('问候',函数(名称){
  警报(你好,+姓名);
});

注射器( $注射器

喷油器负责通过 $实际上是创建使用我们提供的code我们的服务实例提供(没有双关语意)。你写一个函数,参数注入任何时候,你看到工作中的喷油器。每个AngularJS应用程序有一个 $注射器,获取应用程序首次启动时创建的;你可以通过注入获得它的持有 $注射器到任何注射功能(是的, $注射器知道如何注入本身!)

一旦你有了 $注射器,您可以通过调用 GET 上它得到一个定义服务的一个实例该服务的名称。例如,

VAR问候= $ injector.get('问候');
问候语(福特prefect');

注射器还负责注射服务纳入功能;例如,你可以神奇地中注入服务的功能,你使用注射器的引用方法;

VAR myFunction的=功能(贺卡){
  问候语(福特prefect');
};
$ injector.invoke(myFunction的);

其值得注意的是,喷油器将只创建一个服务的一次的实例。然后,它缓存无论该服务的名称的提供回报;接下来你问的服务的时候,你就会得到完全相同的对象。

因此​​,要回答你的问题,你可以注入到服务被称为与 $ injector.invoke 任何函数。这包括


  • 控制器定义功能

  • 指令定义功能

  • 过滤器定义功能

  • 提供的 $ GET 方法(又名工厂定义函数)

由于总是返回一个静态值,他们不是通过喷油器调用,因此,你不能用任何东西,然后注入。

配置提供商

您可能想知道为什么会有人打扰建立一个完整的供应商与提供方法,如果工厂等都是容易得多。答案是,提供商允许很多的配置。我们已经提到,当你创建通过提供商的服务(或任何角度的快捷方式给你),你创建一个新的供应商,它定义了服务是如何构建。我的什么也没有的一提的是,这些供应商可以注入配置应用程序的部分,以便你可以与他们进行互动!

首先,角运行应用程序在两个阶段 - 对配置运行阶段。在配置阶段,正如我们所看到的,在这里你可以设置任何供应商是必要的。这也是指令,控制器,过滤器等得到成立。在运行阶段,您可能已经猜到,就是角实际上编译你的DOM并启动您的应用程序。

您可以添加额外的code在这些阶段与 myMod.config myMod.run 功能 - 每次取一个函数过程中特定阶段运行。正如我们在第一部分看到,这些功能是可注射 - 我们我们的第一个code样品中注入内置 $提供服务。然而,值得一提的是,配置阶段,只有供应商可以注入(适用的服务在<$ C $异常C> AUTO 模块 - $提供 $注射器

例如,下面就是不允许

myMod.config(功能(贺卡){
  //将无法正常工作 - 问候是服务的一个实例* *。
  //只为服务供应商可以在配置块被注入。
});

您的做什么的访问是任何的提供商的服务为您所做的:

myMod.config(功能(greetingProvider){
  // 一个OK!
});

有一个重要的例外: S,因为它们不能被改变,被允许在配置块(这是他们从 S)。他们只以他们的名字(无需提供后缀)进行访问。

当你为服务定义的提供商,该提供商被命名为的ServiceProvider ,其中服务是名称服务。现在我们可以使用供应商的力量做做一些更复杂的东西!

myMod.provider('问候',函数(){
  变种文字=你好,;  this.setText =功能(值){
    文本=价值;
  };  这一点。$ GET =功能(){
    复位功能(名称){
      警报(文本+名);
    };
  };
});myMod.config(功能(greetingProvider){
  greetingProvider.setText(你好那里);
});myMod.run(功能(贺卡){
  问候语(福特prefect');
});

现在,我们对我们的供应商叫的setText ,我们可以用它来定制我们警报函数;我们可以访问该提供商在配置阻塞调用此方法和定制服务。当我们终于运行我们的应用程序,我们可以抢问候服务,并尝试一下,看看我们的定制生效。

由于这是一个更为复杂的例子,这里有一个工作演示: http://jsfiddle.net/BinaryMuse/9GjYg/

控制器( $控制器

控制器的功能可以注入,但控制器本身不能被注入到其他的事情。这是因为控制器不通过提供程序创建。取而代之的是 $控制器称为内置角服务,是负责设置你的控制器。当你调用 myMod.controller(...),你实际上访问的这个服务的提供商,就像在最后一节。

例如,当你定义一个控制器是这样的:

myMod.controller('MainController',函数($范围){
  // ...
});

你实际上做的是这样的:

myMod.config(函数($ controllerProvider){
  $ controllerProvider.register('MainController',函数($范围){
    // ...
  });
});

后来,当角需要创建控制器的一个实例,它使用了 $控制器服务(这反过来又使用了 $注射器来调用您的控制器功能,因此它会注入其依赖太)。

过滤器和指令

过滤器指令工作完全相同的方式为控制器; 过滤器使用了一个名为 $过滤器服务及其提供者 $ filterProvider ,而指令使用一个名为服务 $编译及其供应商 $ compileProvider 。有些链接:


  • $过滤器: http://docs.angularjs.org/api/ng.$filter

  • $ filterProvider:<一href=\"http://docs.angularjs.org/api/ng.%24filterProvider\">http://docs.angularjs.org/api/ng.$filterProvider

  • $编译:<一href=\"http://docs.angularjs.org/api/ng.%24compile\">http://docs.angularjs.org/api/ng.$compile

  • $ compileProvider:<一href=\"http://docs.angularjs.org/api/ng.%24compileProvider\">http://docs.angularjs.org/api/ng.$compileProvider

按照其他的例子, myMod.filter myMod.directive 的快捷键来配置这些服务。


因此​​,要总结,这被称为与 $ injector.invoke 任意功能的可注入。这包括,从图表(但不限于):


  • 控制器

  • 指令

  • 工厂

  • 过滤器

  • 提供商 $ GET (定义为提供对象时)

  • 提供商功能(定义提供商作为构造函数时)

  • 服务

提供商创造新的服务的可以注入的东西。这包括:



  • 工厂

  • 提供商

  • 服务


这是说,内置的服务,如 $控制器 $过滤器可以的被注入,并且可以的使用的那些服务,让您与这些方法(即使你定义的东西都没有,自己定义的新的过滤器和控制器的举行,能够注入的东西)。

除此之外,任何喷油器调用的功能,可以与任何供应商提供的服务注入 - 没有限制(除了配置和<$ C $其他C>运行本文列出的差异)。

I'm having a little hard time understanding Dependency Injection in Angular. So my question is, can anyone explain which of the "types", like Controller, Factory, Provider, etc can we inject into others, including other instances of same "type"?

What I'm actually looking for is this table filled with y/n. For cells with same row/column, that means injecting the value of one "type" into another another one with the same "type"

+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
| Can we inject? | Constant | Controller | Directive | Factory | Filter | Provider | Service | Value |
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+
| Constant       |          |            |           |         |        |          |         |       |
| Controller     |          |            |           |         |        |          |         |       |
| Directive      |          |            |           |         |        |          |         |       |
| Factory        |          |            |           |         |        |          |         |       |
| Filter         |          |            |           |         |        |          |         |       |
| Provider       |          |            |           |         |        |          |         |       |
| Service        |          |            |           |         |        |          |         |       |
| Value          |          |            |           |         |        |          |         |       |
+----------------+----------+------------+-----------+---------+--------+----------+---------+-------+

解决方案

Rather that just fill in the table with "yes" and "no" with no explanation, I'll go into a little bit more detail.

[Note, added after finishing: this ended up being... quite a bit longer than I expected. There's a tl;dr at the bottom, but I hope this proves informational.]

[This answer has also been added to the AngularJS wiki: Understanding Dependency Injection]


The Provider ($provide)

The $provide service is responsible for telling Angular how to create new injectable things; these things are called services. Services are defined by things called providers, which is what you're creating when you use $provide. Defining a provider is done via the provider method on the $provide service, and you can get hold of the $provide service by asking for it to be injected into an application's config function. An example might be something like this:

app.config(function($provide) {
  $provide.provider('greeting', function() {
    this.$get = function() {
      return function(name) {
        alert("Hello, " + name);
      };
    };
  });
});

Here we've defined a new provider for a service called greeting; we can inject a variable named greeting into any injectable function (like controllers, more on that later) and Angular will call the provider's $get function in order to return a new instance of the service. In this case, the thing that will be injected is a function that takes a name parameter and alerts a message based on the name. We might use it like this:

app.controller('MainController', function($scope, greeting) {
  $scope.onClick = function() {
    greeting('Ford Prefect');
  };
});

Now here's the trick. factory, service, and value are all just shortcuts to define various parts of a provider--that is, they provide a means of defining a provider without having to type all that stuff out. For example, you could write that exact same provider just like this:

app.config(function($provide) {
  $provide.factory('greeting', function() {
    return function(name) {
      alert("Hello, " + name);
    };
  });
});

It's important to understand, so I'll rephrase: under the hood, AngularJS is calling the exact same code that we wrote above (the $provide.provider version) for us. There is literally, 100% no difference in the two versions. value works just the same way--if whatever we would return from our $get function (aka our factory function) is always exactly the same, we can write even less code using value. For example, since we always return the same function for our greeting service, we can use value to define it, too:

app.config(function($provide) {
  $provide.value('greeting', function(name) {
    alert("Hello, " + name);
  });
});

Again, this is 100% identical to the other two methods we've used to define this function--it's just a way to save some typing.

Now you probably noticed this annoying app.config(function($provide) { ... }) thing I've been using. Since defining new providers (via any of the given methods above) is so common, AngularJS exposes the $provider methods directly on the module object, to save even more typing:

var myMod = angular.module('myModule', []);

myMod.provider("greeting", ...);
myMod.factory("greeting", ...);
myMod.value("greeting", ...);

These all do the same thing as the more verbose app.config(...) versions we used previously.

The one injectable I've skipped so far is constant. For now, it's easy enough to say that it works just like value. We'll see there's one difference later.

To review, all these pieces of code are doing the exact same thing:

myMod.provider('greeting', function() {
  this.$get = function() {
    return function(name) {
      alert("Hello, " + name);
    };
  };
});

myMod.factory('greeting', function() {
  return function(name) {
    alert("Hello, " + name);
  };
});

myMod.value('greeting', function(name) {
  alert("Hello, " + name);
});

The Injector ($injector)

The injector is responsible for actually creating instances of our services using the code we provided via $provide (no pun intended). Any time you write a function that takes injected arguments, you're seeing the injector at work. Each AngularJS application has a single $injector that gets created when the application first starts; you can get a hold of it by injecting $injector into any injectable function (yes, $injector knows how to inject itself!)

Once you have $injector, you can get an instance of a defined service by calling get on it with the name of the service. For example,

var greeting = $injector.get('greeting');
greeting('Ford Prefect');

The injector is also responsible for injecting services into functions; for example, you can magically inject services into any function you have using the injector's invoke method;

var myFunction = function(greeting) {
  greeting('Ford Prefect');
};
$injector.invoke(myFunction);

Its worth noting that the injector will only create an instance of a service once. It then caches whatever the provider returns by the service's name; the next time you ask for the service, you'll actually get the exact same object.

So, to answer your question, you can inject services into any function that is called with $injector.invoke. This includes

  • controller definition functions
  • directive definition functions
  • filter definition functions
  • the $get methods of providers (aka the factory definition functions)

Since constants and values always return a static value, they are not invoked via the injector, and thus you cannot inject then with anything.

Configuring Providers

You may be wondering why anyone would bother to set up a full-fledged provider with the provide method if factory, value, etc. are so much easier. The answer is that providers allow a lot of configuration. We've already mentioned that when you create a service via the provider (or any of the shortcuts Angular gives you), you create a new provider that defines how that service is constructed. What I didn't mention is that these providers can be injected into config sections of your application so you can interact with them!

First, Angular runs your application in two-phases--the config and run phases. The config phase, as we've seen, is where you can set up any providers as necessary. This is also where directives, controllers, filters, and the like get set up. The run phase, as you might guess, is where Angular actually compiles your DOM and starts up your app.

You can add additional code to be run in these phases with the myMod.config and myMod.run functions--each take a function to run during that specific phase. As we saw in the first section, these functions are injectable--we injected the built-in $provide service in our very first code sample. However, what's worth noting is that during the config phase, only providers can be injected (with the exception of the services in the AUTO module--$provide and $injector).

For example, the following is not allowed:

myMod.config(function(greeting) {
  // WON'T WORK -- greeting is an *instance* of a service.
  // Only providers for services can be injected in config blocks.
});

What you do have access to are any providers for services you've made:

myMod.config(function(greetingProvider) {
  // a-ok!
});

There is one important exception: constants, since they cannot be changed, are allowed to be injected inside config blocks (this is how they differ from values). They are accessed by their name alone (no Provider suffix necessary).

Whenever you defined a provider for a service, that provider gets named serviceProvider, where service is the name of the service. Now we can use the power of providers do do some more complicated stuff!

myMod.provider('greeting', function() {
  var text = 'Hello, ';

  this.setText = function(value) {
    text = value;
  };

  this.$get = function() {
    return function(name) {
      alert(text + name);
    };
  };
});

myMod.config(function(greetingProvider) {
  greetingProvider.setText("Howdy there, ");
});

myMod.run(function(greeting) {
  greeting('Ford Prefect');
});

Now we have a function on our provider called setText that we can use to customize our alert; we can get access to this provider in a config block to call this method and customize the service. When we finally run our app, we can grab the greeting service, and try it out to see that our customization took effect.

Since this is a more complex example, here's a working demonstration: http://jsfiddle.net/BinaryMuse/9GjYg/

Controllers ($controller)

Controller functions can be injected into, but controllers themselves can't be injected into other things. That's because controllers aren't created via the provider. Instead, there is a built-in Angular service called $controller that is responsible for setting up your controllers. When you call myMod.controller(...), you're actually accessing this service's provider, just like in the last section.

For example, when you define a controller like this:

myMod.controller('MainController', function($scope) {
  // ...
});

What you're actually doing is this:

myMod.config(function($controllerProvider) {
  $controllerProvider.register('MainController', function($scope) {
    // ...
  });
});

Later, when Angular needs to create an instance of your controller, it uses the $controller service (which in turn uses the $injector to invoke your controller function so it gets its dependencies injected too).

Filters and Directives

filter and directive work exactly the same way as controller; filter uses a service called $filter and its provider $filterProvider, while directive uses a service called $compile and its provider $compileProvider. Some links:

As per the other examples, myMod.filter and myMod.directive are shortcuts to configuring these services.


So, to summarize, any function that gets called with $injector.invoke can be injected into. This includes, from your chart (but is not limited to):

  • controller
  • directive
  • factory
  • filter
  • provider $get (when defining provider as an object)
  • provider function (when defining provider as a constructor function)
  • service

The provider creates new services that can be injected into things. This includes:

  • constant
  • factory
  • provider
  • service
  • value

That said, built-in services like $controller and $filter can be injected, and you can use those service to get hold of the new filters and controllers you defined with those methods (even though the things you defined aren't, by themselves, able to be injected into things).

Other than that, any injector-invoked function can be injected with any provider-provided service--there is no restriction (other than the config and run differences listed herein).

这篇关于什么&QUOT;东西&QUOT;可以注入其他人Angular.js?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆