gpt4 book ai didi

angular - 为什么必须提供angular2组件构造函数参数

转载 作者:太空狗 更新时间:2023-10-29 18:15:32 26 4
gpt4 key购买 nike

我是 Angular 的新手。当我在做 Heros 教程时,我注意到组件构造函数参数的类型必须是依赖项。换句话说,我必须将它包含在 providers 数组中。

例如:

import { SomeServiceClass } from '...';
@Component({
...
})
export class MyComponent implements OnInit {

constructor(input1: SomeServiceClass) { }

ngOnInit() {
}
}

除非我在 providers 数组中包含 SomeServiceClass,否则这段代码将无法运行。我尝试了 input1: string。也不行!我相信这是完全有效的 typescript 代码。问题一定出在 angular2 实例化组件类的方式上。

问题 1:组件类实际上是如何被 Angular 实例化的?

而且,由于我从未实例化服务类,所以我无法想象将哪个服务类实例传递给组件构造函数。

问题 2:angular 是创建一个服务实例供每个组件使用,还是为每个组件生成一个服务实例?

最佳答案

This code is not going to work unless I include SomeServiceClass in providers array. I tried input1: string. It doesn't work neither! I believe it is totally valid typescript code. The problem must be the way angular2 instantiates the component classes.

您需要将 SomeServiceClass 添加到 somengModuleproviders 数组中的原因很简单。 Angular 选择不执行任何基于代码结构的依赖分析。他们本可以在注入(inject)组件中使用 ES 模块导入来解决依赖关系并自动注册它。

作为证据,Aurelia正是这样做的。

换句话说,在 Aurelia 中,以下足以注入(inject)和使用依赖项

import {autoinject} from 'aurelia-framework';
import {SomeServiceClass} from '...';

@autoinject export class MyComponent {
constructor(input1: SomeServiceClass) {}
}

而且有效。

How are component classed actually instantiated by Angular?

And, since I never instantiate service class, I can't imagine which service class instance is passed to component constructor.

JavaScript 中的类实际上是构造函数,构造函数实际上是美化的工厂函数,工厂函数实际上是美化的函数。

这是什么意思?

这意味着 Angular(和大多数 DI 框架)在首次请求时通过使用 new 调用提供的类来简单地创建一个服务实例。

此类代码的简化版本可能如下所示

function instantiateComponent<T>(Component: new (...args: any[]) => T) {
const requiredDependencies = resolveDependencies(Component);

return new Component(...requiredDependencies);
}

function resolveDependencies(Dep: new (...args: any[]) => any): object[] {
const requiredDependencies = metaDataUtils.getDependencies(Dep);

return requiredDependencies.map(Dep => {
const alreadyCreatedDependency = injectorCache.find(dep => dep instanceof Dep);

if(alreadyCreatedDependency !== undefined) {
return alreadyCreatedDependency;
}
else {
const requiredDependencies = metaDataUtils.getDependencies(Dep);

// resolution is recursive
const newDependency = new Dep(...requiredDependencies.map(resolveDependencies));

injectorCache.push(newDependency);

return newDependency;
}
});
}

Does angular create one instance of service to be used by every component or it generates one instance for each component?

这个有点棘手,默认情况下每个应用程序只创建一个实例。

这是一个应用程序级别的单例,所有请求它的组件都会收到相同的实例。

但是,Angular 中也有不同的隐式和显式行为。

如果延迟加载的 ngModule 在其 providers 数组中列出了相同的服务,则会创建第二个实例,并且该实例将由延迟加载模块的子级共享.这实际上是一种过度简化,但它已经令人困惑,并且考虑到模块是否延迟加载是由其消费者决定的,它可能会导致严重和微妙的错误。

最后,组件可以在 @Component 元数据中显式声明自己的 providers。这样做的任何组件都将创建一个新的服务实例,并由该组件的所有实例共享。

注意:您说的时候要具体

I noticed type of component constructor parameters must be a dependency.

你并不完全正确。依赖关系不是类型,它们是。 TypeScript 类型在编译时被完全删除,实际注入(inject)的是值。类是一个值

class C {}

但是 TypeScript 也会从它的声明中推断出某些类型的存在。但是注入(inject)的是值C,而不是类型C

关于angular - 为什么必须提供angular2组件构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47293757/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com