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

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

问题描述

我有点难以理解角度的依赖注入。所以我的问题是,任何人都可以解释哪些类型,像控制器,工厂,提供者等,我们可以注入其他人,包括其他相同的类型的实例?

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"?

我正在寻找的是这张表填满了y / n。对于具有相同列/列的单元格,这意味着将一个类型的值注入另一个具有相同类型的另一个值。

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在完成后添加:这最终是...比我预期的要长得多。在底部有一个tl; dr,但我希望这样证明了信息。]

[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.]

[这个答案也被添加到AngularJS wiki:了解依赖关系注入]

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

$ provide 服务负责告诉Angular如何创造新的注射用品;这些东西叫做服务。服务由 providers 所定义,这是您在使用 $ offers 时创建的内容。通过 $ provide 服务上的提供者方法定义提供者,您可以扣住code> $提供服务,要求将其注入到应用程序的 config 函数中。一个例子可能是这样的:

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);
      };
    };
  });
});

这里我们定义了一个名为 greeting ;我们可以将一个名为 greeting 的变量注入任何可注入函数(如控制器,稍后更多),Angular将调用提供者的 $ get 函数为了返回一个新的服务实例。在这种情况下,将被注入的东西是一个函数,它基于一个名称参数和 alert sa消息名字。我们可能会这样使用:

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');
  };
});

现在这是诀窍。 code>,服务都是定义提供商各个部分的快捷方式 - 是,它们提供了定义提供者的方法,而不必输入所有的东西。例如,您可以这样写:完全相同的提供者

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);
    };
  });
});

重要的是要理解,所以我会改写:在引擎盖下,AngularJS正在调用完全相同的代码,我们在上面写的( $ provide.provider 版本) 我们。在这两个版本中,字面上有100%没有区别。 的工作方式相同 - 如果我们从我们的 $ get 函数返回的任何东西(也就是我们的 factory 函数)总是完全一样,我们可以使用编写更少的代码。例如,由于我们总是为我们的 greeting 服务返回相同的函数,我们可以使用来定义它:

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.

现在你可能注意到这个烦人的 app.config(function($ provide){... })我一直在使用的东西由于定义新的提供者(通过上面给定方法的任何)是非常常见的,AngularJS直接在模块对象上公开了 $ provider 方法,保存更多的输入:

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", ...);

这些都与更详细的 app.config(。 .. / code>以前我们使用过的版本。

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.

要查看所有这些代码正在执行 exact 同样的事情:

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);
});



注射器( $ inject



注射器负责实际上使用我们通过 $ provide (没有双关语)提供的代码创建我们的服务实例。任何时候你写一个注入参数的函数,你看到注入器在工作。每个AngularJS应用程序都有一个单独的,它在应用程序首次启动时创建;您可以通过将注入任何注射功能(是的, $ injector 知道如何注射自己!)

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!)

一旦你有$ code $ $注释,你可以通过调用获取上的服务名称。例如,

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.

所以,为了回答您的问题,您可以将注册服务注入使用 $ injector.invoke 调用的函数。这包括

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


  • 控制器定义函数

  • 指令定义函数

  • 过滤器定义函数

  • $ get 提供者的方法(也称为工厂定义函数)

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

由于常量 s和始终返回一个静态值,它们不会通过注入器调用,因此您无法注入任何东西。

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

您可能会想知道为什么任何人都不得不设法使用提供方法的正式提供商, code> factory value 等等都容易得多。答案是提供者允许大量的配置。我们已经提到,当您通过提供商(或任何Angular给您的快捷方式)创建服务时,您将创建一个新的提供程序来定义该服务的构造方式。我没有提到这些提供者可以注入到您的应用程序的 config 部分,以便您可以与他们进行交互!

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!

首先,Angular分两个阶段运行您的应用程序 - config run 阶段。如我们所见, config 阶段是可以根据需要设置任何提供程序的地方。这也是设置指令,控制器,过滤器等的地方。您可能会猜到,运行阶段是Angular实际编译DOM并启动您的应用程序的地方。

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.

您可以使用 myMod.config myMod.run 函数添加要在这些阶段中运行的其他代码在这个特定阶段运行一个功能。正如我们在第一部分看到的,这些功能是可注入的 - 我们在第一个代码示例中注入了内置的 $ provide 服务。然而,值得注意的是,在 config 阶段期间,只有提供商可以注入(除了 AUTO 模块 - $提供 $ inject

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).

例如,以下是不允许

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

您可以访问的是任何提供者 em>用于您所做的服务:

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

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

有一个重要的例外:常量因为它们不能被改变,所以允许在 config 中注入块(这是它们与值的不同 )。他们被单独访问(不需要提供者后缀必需)。

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).

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

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');
});

现在我们在我们的提供程序上有一个函数,名为 setText 我们可以使用它来定制我们的警报;我们可以在 config 块中访问此提供程序来调用此方法并自定义服务。当我们终于运行我们的应用程序,我们可以抓住问候语服务,并尝试看到我们的定制生效。

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.

由于这是一个更复杂的例子,以下是一个工作示范: http://jsfiddle.net/BinaryMuse / 9GjYg /

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

控制器功能可以注入,但控制器本身不能注入其他东西。这是因为控制器不是通过提供程序创建的。相反,有一个内置的角色服务称为 $ controller ,负责设置您的控制器。当您调用 myMod.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.

例如,当你定义一个这样的控制器时: / p>

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) {
    // ...
  });
});



< > $ controller
服务(反过来又使用 $ inject 来调用你的控制器函数,这样它也可以注册它的依赖项。)

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).

过滤器指令的工作方式与 controller 完全相同; 过滤器使用名为 $ filter 的服务及其提供者 $ filterProvider ,而指令使用名为 $ compile 的服务及其提供者 $ compileProvider 。一些链接:

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:

  • $filter: http://docs.angularjs.org/api/ng.$filter
  • $filterProvider: http://docs.angularjs.org/api/ng.$filterProvider
  • $compile: http://docs.angularjs.org/api/ng.$compile
  • $compileProvider: http://docs.angularjs.org/api/ng.$compileProvider

根据其他示例, myMod.filter myMod.directive 是配置这些服务的快捷方式。

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

所以,总结一下,使用 $ injector.invoke 可以注入。这包括从您的图表(但不限于):

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):


  • 控制器

  • 指令

  • 工厂

  • 过滤器

  • 提供者 $ get (当将提供者定义为对象时)

  • 提供程序函数(将提供者定义为构造函数时)

  • 服务

  • 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

内置的服务,如 $ controller $ filter 可以注入,你可以使用这些服务来掌握您使用这些方法定义的新的过滤器和控制器(即使您定义的内容本身不能被注入到事物中)。

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).

除此之外,任何注射器调用的函数都可以注入任何提供者提供的服务 - 没有限制(除了 config 运行此处列出的差异)。

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).

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

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