根据Angular的文件:
允许引用尚未定义的引用。
我相信为了更好地理解forwardref是如何工作的,我们需要理解在javascript的框架下是如何发生的。我将提供一个您可能需要使用forwardref的特定案例的示例,但要考虑到可能会出现其他不同的案例。
我们可能知道,javascript函数被提升到其执行上下文的顶部。函数本身就是对象,其他对象也可以从函数创建。因为函数允许程序员创建对象实例,所以ECMAScript 2015创建了一些语法糖,以便使JavaScript更接近于类语言(如Java)。输入类:
class SomeClassName { }
如果我们进入一个javascript编译器(在我使用babel的情况下)并粘贴它,结果将是:
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var SomeClassName = function SomeClassName() {
_classCallCheck(this, SomeClassName);
};
最有趣的部分是注意到我们的类实际上是后台的一个函数。与函数一样,变量也在其执行上下文中提升。唯一的区别是,虽然我们可以调用函数(因为我们可以引用它的指针,即使它被提升了),但是变量被提升了,并且给了一个未定义的默认值。变量在运行时在赋值的给定行被赋值,可能不是未定义的值。例如:
console.log(name);
var name = 'John Snow';
实际上变成:
var name = undefined;
console.log(name) // which prints undefined
name = 'John Snow';
好吧,考虑到所有这些,我们现在就进入角度。假设我们的应用程序中有以下代码:
import { Component, Inject, forwardRef, Injectable } from '@angular/core';
@Injectable()
export class Service1Service {
constructor(private service2Service: Service2Service) {
}
getSomeStringValue(): string {
return this.service2Service.getSomeStringValue();
}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private service1Service: Service1Service) {
console.log(this.service1Service.getSomeStringValue());
}
}
export class Service2Service {
getSomeStringValue(): string {
return 'Some string value.';
}
}
当然,我们需要提供这些服务。让我们在appmodule中提供它们:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent, Service1Service, Service2Service } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [Service1Service, Service2Service],
bootstrap: [AppComponent]
})
export class AppModule { }
appmodule元数据中的重要一行是:
providers: [Service1Service, Service2Service]
如果运行此代码,将出现以下错误:
嗯,有意思…怎么回事?根据之前的解释,
服务2服务
在后台成为一个函数,但是这个函数被分配到一个变量中。此变量已被提升,但其值未定义。因此,无法解析参数。
输入forwardref
为了解决这个问题,我们有一个漂亮的函数
前馈
. 这个函数的作用是将函数作为参数(在我展示的例子中,我使用了一个箭头函数)。此函数返回一个类。forwardref等待service2service声明,然后触发传递的箭头函数。这将返回创建service2service实例所需的类。因此,app.component.ts代码如下所示:
import { Component, Inject, forwardRef, Injectable } from '@angular/core';
@Injectable()
export class Service1Service {
constructor(@Inject(forwardRef(() => Service2Service)) private service2Service) {
}
getSomeStringValue(): string {
return this.service2Service.getSomeStringValue();
}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private service1Service: Service1Service) {
console.log(this.service1Service.getSomeStringValue());
}
}
export class Service2Service {
getSomeStringValue(): string {
return 'Some string value.';
}
}
最后,根据我提供的示例,forwardref允许我们引用稍后在源代码中定义的类型,防止代码崩溃,并在代码中组织内容的方式上提供更大的灵活性。
我真的希望我的回答对你有用。:)