Par*_*xis 12 dependency-injection typescript angular
我目前正在学习新的 Angular 框架,我正在尝试制作一个动态搜索栏,它接受服务名称作为参数,以便动态解析服务以查询后端服务。
为此,我使用Injector, 并在ngOnInit. 这在使用基于字符串的提供程序时工作正常,但是我的 IDE 指出它已被弃用,我应该使用一个InjectionToken我似乎无法理解的。
我希望以下代码可以工作,因为删除所有实例InjectionToken并将其替换为直接字符串文字有效:
我尝试查看以下文档,但我不太明白,因为我觉得我完全按照它说的做了,但它一直告诉我它不起作用:https : //angular.io/guide/dependency-注射提供者
有人能告诉我我做错了什么吗?
谢谢
模块声明
// app.module.ts
@NgModule({
declarations: [
AppComponent,
SearchBarComponent
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule
],
providers: [
{
provide: new InjectionToken<ISearchable>('CustomerService'), // <-- doesn't work; 'CustomerService' <-- works
useValue: CustomerService
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
搜索栏组件:
// search-bar.component.ts
@Component({
selector: 'search-bar',
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.sass']
})
export class SearchBarComponent implements OnInit {
@Input()
source: string;
private searcher: ISearchable;
constructor(private injector: Injector) {}
ngOnInit() {
// error: Error: No provider for InjectionToken CustomerService!
let token = new InjectionToken<ISearchable>(this.source);
this.searcher = this.injector.get<ISearchable>(token);
// this works, but it's deprecated and will probably break in the future
// this.searcher = this.injector.get(this.source);
console.log(this.searcher);
}
}
Run Code Online (Sandbox Code Playgroud)
使用搜索栏:
<!-- app.component.html -->
<div class="row justify-content-center mb-2">
<div class="col-8">
<search-bar title="Customers" source="CustomerService"></search-bar>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
编辑:这是一个错误示例:
在官方 angular 存储库上询问后,结果证明这是一个简单的解决方案。您不必将服务名称作为字符串传递,而是将令牌通过组件传递到视图中,然后传递到另一个组件中。
我这样做是在我的服务本身旁边进行的,以便更容易跟踪。
@Injectable()
export class CustomerService implements ISearchable { ... }
export const CUSTOMER_SERVICE = new InjectionToken<ISearchable>('CustomerService');
Run Code Online (Sandbox Code Playgroud)
import {CUSTOMER_SERVICE, CustomerService} from "./services/customer/customer.service";
@NgModule({
declarations: [ ... ],
imports: [ ... ],
providers: [
{
provide: CUSTOMER_SERVICE, // That's the token we defined previously
useClass: CustomerService, // That's the actual service itself
}
],
bootstrap: [ ... ],
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
// In your component
import {CUSTOMER_SERVICE} from "./services/customer/customer.service";
@Component({
selector: 'app-root',
template: '<app-search-bar [source]="searcher"></app-search-bar>'
})
export class AppComponent
{
searcher = CUSTOMER_SERVICE;
}
Run Code Online (Sandbox Code Playgroud)
@Component({
selector: 'app-search-bar',
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.sass'],
})
export class SearchBarComponent implements OnInit
{
@Input()
source: InjectionToken<ISearchable>;
private searcher: ISearchable;
constructor(private injector: Injector) {}
ngOnInit()
{
this.searcher = this.injector.get<ISearchable>(this.source);
}
search(query: string)
{
this.searcher.search(query).subscribe(...);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
对于任何仍在为此苦苦挣扎的人来说,这可能就像重新启动 VS Code 一样简单,就像我的情况一样。我不知道为什么,但这为我解决了。当然,我首先尝试了这个,因为我很确定这个错误一开始就是错误的。
| 归档时间: |
|
| 查看次数: |
31617 次 |
| 最近记录: |