sourcetip

각도 주입토큰이 '주입 공급자 없음'을(를) 슬로우합니다.토큰'

fileupload 2023. 7. 17. 21:20
반응형

각도 주입토큰이 '주입 공급자 없음'을(를) 슬로우합니다.토큰'

저는 현재 새로운 Angular 프레임워크를 배우고 있으며 백엔드 서비스를 쿼리할 서비스를 동적으로 해결하기 위해 서비스 이름을 인수로 받아들이는 동적 검색 막대를 만들려고 합니다.

이를 위해 저는 사용하고 있습니다.Injector다음 시간 동안 서비스 로드ngOnInit 기반 공급자를 되지 않으며 IDE를 사용해야 합니다.InjectionToken머리를 감을 수가 없는 것 같아요.

의 모든 인스턴스를 제거하므로 다음 코드가 작동할 것으로 예상했습니다.InjectionToken직접 문자열 리터럴 작업으로 대체합니다.

저는 다음 문서를 보려고 했지만, 제가 정확히 말한 대로 한 것 같아서 잘 이해하지 못했는데, 계속 작동하지 않는다는 메시지가 나타납니다. https://angular.io/guide/dependency-injection-providers

누가 제가 뭘 잘못하고 있는지 말해줄 수 있나요?
합니다.

모듈 선언

// 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 { }

검색 줄 구성 요소:

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

검색 줄 사용:

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

편집: 다음은 오류가 발생한 예입니다.

https://stackblitz.com/edit/angular-3admbe

공식 각도 저장소에 문의한 결과 간단한 해결책으로 나타났습니다.서비스 이름을 문자열로 전달하는 대신 토큰을 구성 요소를 통해 보기로 전달하여 다른 구성 요소로 전달할 수 있습니다.

주입 토큰을 전역적으로 정의합니다.

저는 이것을 제 서비스 자체와 함께 더 쉽게 추적할 수 있도록 했습니다.

@Injectable()
export class CustomerService implements ISearchable { ... }

export const CUSTOMER_SERVICE = new InjectionToken<ISearchable>('CustomerService');

앱 공급자에 주입 토큰 등록

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 { }

보기를 통해 토큰을 다른 구성 요소로 전달

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

이제 다른 구성 요소에서 서비스를 동적으로 가져올 수 있습니다.

@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(...);
  }
}

아직도 이 문제로 어려움을 겪고 있는 사람들에게 VS Code를 다시 시작하는 것은 저의 경우와 마찬가지로 간단할 수 있습니다.왜 그런지는 모르겠지만, 그것이 저를 해결해 주었습니다.물론, 저는 이것을 먼저 시도했습니다. 왜냐하면 저는 처음부터 그 오류가 잘못되었다고 확신했기 때문입니다.

AppModule의 공급자 목록에 서비스를 구현하는 대신 우리가 할 수 있는 것은 제공된 것을 추가하는 것입니다.서비스의 삽입 가능 주석에 대한 루트 매개 변수로 들어갑니다.

https://angular.io/guide/providers#providing-a-service

예:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

하지만 한 가지 방법이 더 있습니다. 당신의 방법입니다.서비스를 모듈의 공급자 목록에 추가할 수 있습니다. 이 목록에는 참여가 필요하지 않습니다.토큰. 이미 검사되었기 때문에 공급자 목록에 추가할 수 있습니다.

https://angular.io/guide/providers#provider-scope

예:

@NgModule({
  declarations: [
    AppComponent,
    SearchBarComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [
    CustomerService // <-- You don't need to create any token.
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

당신은 모든 것을 혼동하고 있습니다.

토큰은 일반 객체로 만들어집니다.종속성 주입이 있는 서비스를 사용하여 토큰으로 선언할 수 없습니다.

주문형 서비스를 만들려면 공장을 사용해야 합니다.팩토리는 주어진 속성으로 클래스의 인스턴스를 만드는 함수입니다.

이 예에서는 엔드포인트를 지정된 속성으로 추가했지만 공장에서 원하는 작업을 수행할 수 있습니다.

Stackblitz : https://stackblitz.com/edit/angular-dg1hut?file=src/app/search-bar/search-bar.component.ts

const factory = (http: HttpClient) => new CustomerService(http, '/api/v1/customer')
// ...
providers: [{
  provide: CustomerService,
  useFactory: factory,
  deps: [HttpClient]
}],
export class SearchBarComponent implements OnInit {
  @Input() source: string;
  constructor(private searcher: CustomerService) { }
  ngOnInit() { console.log(this.searcher); }
  search() { return this.searcher.search(''); }
}

2023년 독립형 구성 요소가 있는 Angular 15의 경우, 우리는 경로에서 주입 토큰을 정의해야 합니다. mfe와 립이 있는 나의 상황은 주입 토큰을 가져야 할 경우에 대비하여 우리는 그것들을 투입해야 합니다.entryRoutes.ts배열

export const remoteRoutes: Route[] = [
  {
    path: '',
    component: RemoteEntryComponent,
    children: uiRoutesChildren,
    providers: [
      {
        provide: 'API_URL',
        useValue: API_URL,
      },
    ],
  },
];

출처: https://angular.io/guide/standalone-components

언급URL : https://stackoverflow.com/questions/53317225/angular-injectiontoken-throws-no-provider-for-injectiontoken

반응형