>  기사  >  웹 프론트엔드  >  Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

青灯夜游
青灯夜游앞으로
2022-06-24 15:28:432607검색

이 글은 Angular의 종속성 주입 모드에 대한 심층적인 이해를 제공하고, 종속성 주입 모드의 적용 및 게임 플레이 사례를 공유하는 것이 모든 사람에게 도움이 되기를 바랍니다.

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

1 컴포넌트 트리 레벨 통신 모드 및 디자인 패턴인 인젝션

1.1 컴포넌트 통신 모드

Angular 엔지니어링 개발에서는 일반적으로 입력 속성 바인딩과 출력 이벤트 바인딩 컴포넌트 통신을 사용하지만 입력 출력은 상위 구성요소와 하위 구성요소 간에만 정보를 전달할 수 있습니다. 구성 요소는 호출 관계를 기반으로 구성 요소 트리를 형성합니다. 속성 바인딩과 이벤트 바인딩만 있는 경우 두 개의 비직접 관계 구성 요소는 각 연결 지점 자체를 통해 통신해야 하며 중개자는 수행하는 일부 작업을 지속적으로 처리하고 전달해야 합니다. 정보를 알 필요가 없습니다(왼쪽 그림 1). Angular에서 제공하는 Injectable Service는 모듈, 구성 요소 또는 명령어로 제공될 수 있으며 생성자에서 주입과 결합되어 이 문제를 해결할 수 있습니다(그림 1 오른쪽). [관련 튜토리얼 추천: "angular tutorial"]

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

그림 1 컴포넌트 통신 모드

왼쪽 그림은 부모-자식 컴포넌트를 통해서만 정보를 전송합니다. 노드 a와 노드 b는 통신을 위해 많은 노드를 거쳐야 합니다. 노드 c가 어떤 구성을 통해 노드 b를 제어하려면, 그들 사이의 노드도 추가 속성이나 이벤트를 설정하여 해당 정보를 투명하게 전송해야 합니다. 오른쪽의 의존성 주입 모드에서는 노드 c가 노드 a와 b가 통신할 수 있는 서비스를 제공할 수 있으며, 노드 a는 노드 c가 제공하는 서비스와 직접 통신하고, 마지막으로 노드 b도 노드 c가 제공하는 서비스와 직접 통신합니다. , 통신이 단순화되고 중간 노드는 컨텐츠의 이 부분과 결합되지 않으며 상위 구성 요소와 하위 구성 요소 간에 발생하는 통신에 대한 명확한 인식이 없습니다.

1.2 종속성 주입을 사용하여 제어 역전 달성

종속성 주입(DI)은 Angular에만 있는 것이 아니라 IOC(제어 역전) 설계 패턴을 구현하는 수단입니다. -수동 인스턴스화의 결합 문제는 모든 리소스가 리소스를 사용하는 두 당사자에 의해 관리되는 것이 아니라 리소스 센터 또는 제3자에 의해 제공되므로 많은 이점을 가져올 수 있다는 것입니다. 첫째, 리소스를 중앙 집중식으로 관리하면 리소스를 구성하고 관리하기 쉽습니다. 둘째, 자원을 사용하여 두 당사자 간의 의존도를 줄이는데, 이를 결합이라고 합니다.

현실 세계와 비유하자면 연필과 같은 제품을 구입할 때 연필과 같은 종류의 제품을 구입하려면 매장만 찾으면 됩니다. 우리는 연필이 어디서 생산되는지, 아니면 상관하지 않습니다. 나무심과 연필심을 접착하는 방법 예, 연필의 쓰기 기능을 완성하는 데만 필요합니다. 우리는 특정 연필 제조업체나 공장과 접촉하지 않습니다. 매장의 경우 적절한 채널에서 연필을 구매할 수 있으며 리소스 구성 가능성을 실현할 수 있습니다.

코딩 시나리오와 결합하면, 더 구체적으로 말하면 사용자는 인스턴스를 삽입하고 사용하기 위해 명시적으로 인스턴스(새 작업)를 생성할 필요가 없습니다. 인스턴스 생성은 공급자에 의해 결정됩니다. 리소스 관리는 토큰을 통해 이루어집니다. 공급자나 인스턴스 생성에 신경 쓰지 않기 때문에 사용자는 일부 로컬 주입 방법(토큰의 보조 구성)을 사용하여 최종적으로 인스턴스 교체 및 애플리케이션 및 측면 프로그래밍(AOP)을 달성할 수 있습니다. ) 서로를 보완합니다.

2 Angular의 종속성 주입

종속성 주입은 Angular 프레임워크의 가장 중요한 핵심 모듈 중 하나입니다. 서비스 유형 주입뿐만 아니라 구성 요소 트리 자체가 함수 및 값 주입 종속성 트리입니다. 주입하여 사용할 수도 있습니다. 즉, Angular 프레임워크에서 하위 구성 요소는 상위 구성 요소의 토큰(일반적으로 클래스 이름)을 통해 상위 구성 요소 인스턴스를 주입할 수 있습니다. 컴포넌트 라이브러리 개발에서는 파라미터 마운팅, 상태 공유, 심지어 부모 컴포넌트가 위치한 노드의 DOM 획득 등 부모 컴포넌트를 주입함으로써 상호 작용과 통신이 이루어지는 경우가 많습니다.

2.1 종속성 해결

Angular 주입을 사용하려면 먼저 주입 해결 프로세스를 이해해야 합니다. node_modules의 구문 분석 프로세스와 유사하게 종속성이 발견되지 않으면 종속성은 항상 상위 레이어까지 버블링되어 종속성을 찾습니다. Angular의 이전 버전(v6 이전)에서는 주입 구문 분석 프로세스를 다중 레벨 모듈 인젝터, 다중 레벨 컴포넌트 인젝터 및 요소 인젝터로 나눕니다. 새 버전(v9 이후)은 2단계 모델로 단순화되었습니다. 첫 번째 쿼리 체인은 정적 DOM 수준 요소 인젝터, 구성 요소 인젝터 등으로 집합적으로 요소 인젝터라고 하며, 다른 쿼리 체인은 모듈 인젝터입니다. . 파싱 ​​순서와 파싱 실패 후 기본값은 공식 코드 주석 문서(provider_flag)에 더 명확하게 설명되어 있습니다.

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

그림 2 2레벨 인젝터의 종속성 검색 프로세스(이미지 소스)

즉, 구성 요소/명령어 및 구성 요소/명령어 수준에서 주입된 콘텐츠를 제공하면 먼저 요소의 종속성을 찾습니다. 컴포넌트 뷰에서 루트 요소까지, 찾을 수 없는 경우 요소가 있는 모듈에서 루트 모듈과 플랫폼 모듈이 참조될 때까지(모듈 참조 및 라우팅 지연 로딩 참조 포함) 모듈의 상위 모듈을 검색합니다. 현재 위치.

여기서 인젝터에는 상속이 있습니다. 요소 인젝터는 상위 요소 인젝터의 검색 기능을 생성하고 상속할 수 있으며 모듈 인젝터도 비슷합니다. 연속 상속 후에는 js 객체의 프로토타입 체인과 비슷해집니다.

2.2 구성 공급자

종속성 해결의 순서 우선순위를 이해하면 적절한 수준의 콘텐츠를 제공할 수 있습니다. 우리는 이미 모듈 주입과 요소 주입이라는 두 가지 유형이 있다는 것을 알고 있습니다.

  • 모듈 인젝터: @NgModule의 메타데이터 속성에서 공급자를 구성할 수 있으며, v6 이후에 제공되는 @Injectable 문을 사용할 수도 있습니다. ProvideIn 문은 모듈 이름, '루트' 등입니다. (실제로 루트 모듈 위에 Platform과 Null이라는 두 개의 인젝터가 있습니다. 여기서는 논의하지 않습니다.)

  • 요소 인젝터: 공급자, viewProviders 또는 공급자.

지시문의 @Directive 메타데이터에 있습니다. 실제로 @Injectable 데코레이터를 사용하여 모듈 인젝터를 선언하는 것 외에도 요소 인젝터로 선언할 수도 있습니다. 싱글톤을 구현하기 위해 루트에 제공되는 것으로 선언되는 경우가 더 많습니다. 모듈이나 구성 요소가 공급자를 명시적으로 선언하는 것을 방지하기 위해 클래스 자체를 통해 메타데이터를 통합합니다. 이러한 방식으로 클래스에 구성 요소 지시문 서비스와 이를 주입할 다른 클래스가 없으면 유형 선언에 연결된 코드가 없습니다. 컴파일러는 이를 무시할 수 있으므로 트리 흔들림이 달성됩니다.

InjectionToken을 선언할 때 값을 직접 부여하는 방법도 있습니다.

다음은 이러한 메서드에 대한 약식 템플릿입니다.

@NgModule({  providers: [
    // 模块注入器
  ]
})
export class MyModule {}
@Component({  providers: [
    // 元素注入器 - 组件
  ],  
  viewProviders: [
      // 元素注入器- 组件视图
  ]
})
export class MyComponent {}
@Directive({  providers: [
   // 元素注入器 - 指令
 ]
})
export class MyDirective {}
@Injectable({
 providedIn: 'root'
})
export class MyService {}
export const MY_INJECT_TOKEN = new InjectionToken<myclass>('my-inject-token', {
 providedIn: 'root',
 factory: () => {
    return new MyClass();
 }
});</myclass>

종속성 위치를 제공하는 다양한 옵션에 따라 약간의 차이가 발생하며 이는 궁극적으로 패키지 크기, 주입할 수 있는 종속성 범위 및 종속성의 수명 주기에 영향을 미칩니다. 싱글톤(루트), 서비스 격리(모듈), 다중 편집 창(구성 요소) 등과 같은 다양한 시나리오에 적용 가능한 솔루션이 다릅니다. 부적절한 공유 정보 또는 중복 코드 패키징을 피하기 위해 합리적인 위치를 선택해야 합니다.

2.3 다양한 가치 기능 도구

인스턴스 주입만 제공하면 Angular 프레임워크 종속성 주입의 유연성을 발휘할 수 없습니다. Angular는 다양한 유연한 주입 도구를 제공합니다. useClass는 정적 값을 사용하고, useExisting은 기존 인스턴스를 재사용할 수 있으며, useFactory는 지정된 deps 및 지정된 생성자 매개변수를 사용하여 매우 다양하게 구성됩니다. 클래스의 토큰 토큰을 잘라서 준비한 다른 인스턴스로 교체할 수 있으며, 토큰을 생성하여 값이나 인스턴스를 먼저 저장한 후 나중에 필요할 때 다시 교체하여 사용할 수도 있습니다. 인스턴스의 로컬 정보는 다른 객체나 속성 값에 매핑됩니다. 여기서의 게임 플레이는 이후 사례를 통해 설명할 것이므로 여기서는 더 이상 설명하지 않겠습니다. 공식 홈페이지에도 참고할 수 있는 사례가 많이 있습니다.

2.4 주입 소비자 및 데코레이터

Angular의 주입은 생성자에서 주입할 수 있거나 get 메서드를 통해 기존에 주입된 요소를 가져오는 주입기를 얻을 수 있습니다.

Angular는 주입 시 표시할 데코레이터 추가를 지원합니다.

  • @Host()는 버블링을 제한하고
  • @Self()는 요소 자체로 제한하고
  • @SkipSelf()는 요소 자체로 제한합니다.
  • @Optional () 선택사항으로 표시됨
  • @Inject()는 사용자 정의 토큰 토큰으로 제한됨

여기에 "@Self 또는 @Optional @Host? Angular DI 데코레이터에 대한 시각적 가이드."라는 기사가 있습니다. 상위 구성 요소와 하위 구성 요소 간에 서로 다른 데코레이터를 사용하면 적중됩니다.

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

그림 3 주입된 다양한 데코레이터의 필터링 결과

2.4.1 보충: 호스트 뷰와 @Host

중에서 가장 이해하기 어려운 것은 아마도 @Host일 것입니다. 여기에 @Host 관련 보충이 있습니다. 지침. @Host 데코레이터에 대한 공식적인 설명은

...호스트 요소에 도달할 때까지 모든 인젝터에서 종속성을 검색합니다

입니다.

여기서 호스트는 호스트를 의미합니다. @Host 데코레이터는 쿼리 범위를 호스트 요소로 제한합니다. 호스트 요소란 무엇입니까? 구성 요소 B가 구성 요소 A의 템플릿에서 사용되는 구성 요소인 경우 구성 요소 A의 인스턴스는 구성 요소 B 인스턴스의 호스트 요소입니다. 구성 요소 템플릿에 의해 생성된 콘텐츠를 보기라고 합니다. 동일한 보기가 구성 요소마다 다를 수 있습니다. 컴포넌트 A가 자체 템플릿 범위 내에서 컴포넌트 B를 사용하는 경우(그림 4 참조), A의 템플릿 콘텐츠로 구성된 뷰(빨간색 상자 부분)는 컴포넌트 A의 내장된 뷰이고, 컴포넌트 B는 이 뷰 내에 있으므로 B의 경우 , 이 보기는 B의 호스트 보기입니다. 데코레이터 @Host는 검색 범위를 호스트 뷰로 제한합니다. 호스트 뷰가 발견되지 않으면 버블링되지 않습니다.

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

그림 4 인라인 뷰 및 호스트 뷰

3 사례 및 게임플레이

실제 사례를 통해 종속성 주입이 작동하는 방식, 오류를 해결하는 방법 및 기타 수행할 수 있는 작업을 살펴보겠습니다.

3.1 사례 1: 모달 창은 동적 구성 요소를 생성하지만 구성 요소를 찾을 수 없습니다.

DevUI 구성 요소 라이브러리의 모달 창 구성 요소는 모달 상자를 팝업할 수 있고 다음과 같이 구성할 수 있는 ModalService 서비스를 제공합니다. 자동으로 정의된 구성 요소. 경영학도들은 이 구성 요소를 사용할 때 패키지가 사용자 정의 구성 요소를 찾을 수 없다는 오류를 보고하는 경우가 많습니다.

예를 들어 다음 오류 보고서는 다음과 같습니다.

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

그림 5 ModalService를 사용할 때 EditorX를 참조하는 구성 요소를 생성할 때 오류 보고서에서 해당 서비스 공급자를 찾을 수 없습니다.

ModalService가 사용자 정의 구성 요소를 생성하는 방법을 분석합니다. ModalService 소스 코드 기능 열기 52행과 95행. 보시다시피 comComponentFactoryResolver가 전달되지 않으면 ModalService에서 삽입한 comComponentFactoryResolver가 사용됩니다. 대부분의 경우 기업은 루트 모듈에 DevUIModule을 한 번 도입하지만 현재 모듈에는 ModalModule을 도입하지 않습니다. 즉, 의 현재 상황은 이렇다. 그림 6에 따르면 ModalService의 인젝터에는 EditorXModuleService가 없습니다. componentFactoryResolver如果没有传入就使用ModalService注入的componentFactoryResolver。而大多数情况下,业务会在根模块引入一次DevUIModule,但是不会在当前模块里引入ModalModule。也就是现状图6是这样的。根据图6,ModalService的injector内是没有EditorXModuleService的。

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

图6 模块服务提供关系图

根据注入器的继承,解决办法有四个:

  • 把 EditorXModule 放到 ModalModule 声明的地方,这样注入器就能找到EditorXModule提供的EditorModuleService —— 这是最糟糕的一种解法,本身loadChildren实现的懒加载就是为了减少首页模块的加载,结果是子页内需要用到的内容却放在AppModule,首次加载就把富文本的大模块给加载了,加重了FMP(First Meaningful Paint),不可采取。

  • 在引入 EditorXModule 且使用 ModalService 的模块里引入 ModalService —— 可取。仅有一种情况不太可取,就是调用 ModalService 的是另一个靠顶层的公共 Service,这样还是把不必要的模块放在了上层去加载。

  • 在触发使用ModalService的组件,注入当前模块的componentFactoryResolver,并传给ModalService的open函数参数 —— 可取, 可以在真正使用的地方再引入EditorXModule。

  • 在使用的模块里,手动提供一个ModalService —— 可取,解决了注入搜索的问题。

四种方法其实都是在解决 ModalService 所用的componentFactoryResolver

Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

사진 6 모듈 서비스 제공 관계 다이어그램

인젝터의 상속에 따라 4가지 솔루션이 있습니다.

  • ModalModule이 선언된 곳에 EditorXModule을 넣고, 인젝터는 EditorXModule에서 제공하는 EditorModuleService를 찾을 수 있습니다. 이는 최악의 솔루션입니다. loadChildren 자체에서 구현한 지연 로딩은 홈페이지 모듈의 로딩을 줄이기 위한 것입니다. AppModule에 배치됩니다. 처음으로 로드하면 서식 있는 텍스트의 큰 모듈이 로드되므로 FMP(First Meaningful Paint)가 증가하므로 채택할 수 없습니다.

EditorXModule을 도입하고 ModalService를 사용하는 모듈에 ModalService를 도입하는 것이 좋습니다. 바람직하지 않은 상황은 단 하나뿐입니다. 즉, ModalService를 호출하는 것은 또 다른 최상위 공용 서비스이며 로드를 위해 불필요한 모듈을 상위 계층에 배치하는 것입니다.

  • ModalService를 사용하는 컴포넌트를 트리거할 때 현재 모듈의 comComponentFactoryResolver를 삽입하고 이를 ModalService의 개방형 함수 매개변수에 전달합니다. 여기에 EditorXModule을 도입하는 것이 좋습니다. 실제로 사용됩니다.

  • Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)사용된 모듈에서는 검색 주입 문제를 해결하는 ModalService를 수동으로 제공하는 것이 좋습니다.
  • 네 가지 메소드는 실제로 ModalService에서 사용하는 comComponentFactoryResolver 인젝터의 내부 체인에 있는 EditorXModuleService 문제를 해결하고 있습니다. 검색 체인이 두 가지 수준에 있도록 함으로써 이 문제를 해결할 수 있습니다. Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    지식 포인트 요약

    : 모듈 인젝터 상속 및 검색 범위. 🎜🎜🎜3.2 사례 2: CdkVirtualScrollFor가 CdkVirtualScrollViewport를 찾을 수 없습니다🎜🎜🎜보통 동일한 템플릿을 여러 곳에서 사용할 때 템플릿을 통해 공통 부분을 추출합니다. 이전에 DevUI Select 구성 요소를 개발할 때 개발자는 공통 부분을 추출하고 싶었습니다. . 오류가 보고되었습니다. 🎜🎜🎜🎜🎜🎜🎜🎜그림 7 코드 이동 및 삽입 오류를 찾을 수 없음🎜

    CdkVirtualScrollFor 명령이 CdkVirtualScrollViewport를 주입해야 하기 때문입니다. 그러나 요소 주입 인젝터 상속 시스템은 정적 AST 관계의 DOM을 상속하므로 동적 관계를 사용할 수 없으므로 다음과 같은 쿼리 동작이 발생하고 검색이 실패합니다. .

    Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 8 요소 인젝터 쿼리 체인 검색 범위

    최종 해결 방법: 1) 원본 코드 위치를 변경하지 않고 유지하거나 2) 이를 찾으려면 전체 템플릿을 포함해야 합니다.

    Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 9 내장된 전체 모듈을 통해 CdkVitualScrollFo는 CdkVirtualScrollViewport를 찾을 수 있습니다(솔루션 2)

    지식 포인트 요약: 요소 인젝터의 쿼리 체인은 정적 템플릿의 DOM 요소 조상입니다.

    3.3 사례 3: 양식 확인 구성 요소가 하위 구성 요소로 캡슐화되어 확인할 수 없습니다.

    이 사례는 이 블로그 "Angular: Nested templatedriven form"에서 가져온 것입니다.

    양식 유효성 검사를 사용할 때도 동일한 문제가 발생했습니다. 그림 10에서 볼 수 있듯이 몇 가지 이유로 우리는 재사용을 위해 세 필드의 주소를 구성 요소로 캡슐화합니다.

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 10 양식의 세 가지 주소 필드를 하위 구성 요소로 캡슐화합니다.

    이제 오류를 발견하게 됩니다. ngModelGroup에는 내부에 ControlContainer가 필요합니다. ngForm 지시문에서 제공하는 콘텐츠인 호스트입니다. ngModelGroup需要一个host内部的ControlContainer,也就是ngForm指令提供的内容。

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    图11 ngModelGroup 找不到ControlContainer

    查看ngModelGroup代码可以看到它只添加了host装饰器的限制。

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    图12 ng_model_group.ts限定了注入ControlContainer的范围

    这里可以使用viewProvider搭配usingExisting给AddressComponent的宿主视图增加ControlContainer的Provider

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    图13 使用viewProviders给嵌套组件提供外部的Provider

    知识点小结:viewProvider 和 usingExisting 搭配的妙用。

    3.4 案例四:拖拽模块提供的Service,由于懒加载,不是单例了,导致无法互相拖拽

    内部的业务平台有涉及跨多个模块的拖拽,由于涉及了loadChildren懒加载,每个模块会单独打包DevUI组件库的DragDropModule,该Module提供了一个DragDropService。拖拽指令分为可拖起指令Draggable和可放置指令Droppable,两个指令通过DragDropService进行通信。 本来引入同一个模块使用模块提供的Service是可以通信的,但是懒加载后DragDropModule模块被打包了两次,也对应产生两份隔离的实例。这时候处于一个懒加载模块里的Draggable指令就无法与另一个懒加载模块里的Droppable指令进行通信了,因为此时DragDropService并不是同个实例了。

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    图14 懒加载模块导致服务不是同一实例/单例

    这里明显我们的述求是需要单例,而单例的做法通常就是providerIn: 'root'

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    사진 11 ngModelGroup이 ControlContainer를 찾을 수 없습니다

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)ngModelGroup 코드를 보면 호스트 데코레이터의 제한만 추가하는 것을 볼 수 있습니다.

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    사진 12 ng_model_group.ts는 ControlContainer 주입 범위를 제한합니다1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    여기서 usingExisting과 함께 viewProvider를 사용하여 AddressComponent

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    🎜그림 13 viewProvider를 사용하여 중첩된 구성 요소에 외부 공급자 제공🎜🎜🎜지식 요점 요약🎜: viewProvider 및 기존 배열 사용이 훌륭합니다. 🎜

    🎜3.4 사례 4: 드래그 앤 드롭 모듈에서 제공하는 서비스가 지연 로딩으로 인해 더 이상 싱글톤이 아니므로 서로 드래그 앤 드롭이 불가능해짐🎜🎜🎜 내부 비즈니스 플랫폼에는 여러 모듈 드래그가 포함됩니다. loadChildren의 지연 로딩으로 인해 각 모듈은 DragDropService를 제공하는 DevUI 구성 요소 라이브러리의 DragDropModule을 별도로 패키징합니다. 드래그 앤 드롭 지침은 Draggable 지침과 Droppable 지침으로 구분됩니다. 두 지침은 DragDropService를 통해 통신합니다. 원래는 동일한 모듈을 도입하고, 모듈에서 제공하는 서비스를 이용하여 통신이 가능했지만, 지연 로딩 이후 DragDropModule 모듈이 2번 패키징되어 역시 2개의 고립된 인스턴스가 발생하게 되었습니다. 현재 DragDropService는 동일한 인스턴스가 아니기 때문에 지연 로드 모듈의 Draggable 명령은 다른 지연 로드 모듈의 Droppable 명령과 통신할 수 없습니다. 🎜🎜1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)🎜🎜사진 14 모듈의 지연 로딩으로 인해 서비스가 동일한 인스턴스/단일 사례가 되지 않게 됩니다🎜🎜여기서 우리의 요구 사항은 싱글톤이 필요하다는 것이 분명하며, 싱글톤 메서드는 일반적으로 providerIn: 'root'입니다. 그렇다면 컴포넌트 라이브러리의 DragDropService를 모듈 수준에서 제공하지 않고 루트 도메인에서 직접 제공하는 것이 더 좋지 않을까요? 하지만 잘 생각해보면 여기에는 또 다른 문제가 있다. 구성 요소 라이브러리 자체는 다양한 비즈니스에서 사용할 수 있도록 제공됩니다. 일부 비즈니스에서는 페이지의 두 위치에 두 개의 해당 드래그 앤 드롭 그룹이 있는 경우 연결을 원하지 않습니다. 이때 싱글톤은 이러한 모듈 기반의 자연스러운 격리를 파괴합니다. 🎜🎜그렇다면 비즈니스 측면에서 싱글톤 교체를 구현하는 것이 더 합리적일 것입니다. 앞서 언급한 종속성 쿼리 체인을 기억하세요. 요소 인젝터가 먼저 검색됩니다. 발견되지 않으면 모듈 인젝터가 시작됩니다. 따라서 대체 아이디어는 요소 수준 공급자를 제공할 수 있다는 것입니다. 🎜🎜🎜🎜🎜그림 15 확장 메서드를 사용하여 새 DragDropService를 얻고 루트 수준에서 제공된 것으로 표시🎜🎜🎜🎜🎜🎜🎜

    그림 16 동일한 선택기를 사용하여 반복되는 명령을 중첩하고, 구성 요소 라이브러리의 Draggable 명령과 Droppable 명령에 추가 명령을 중첩하고, DragDropService의 토큰을 루트에서 싱글톤을 제공한 DragDropGlobalService로 바꿀 수 있습니다

    As 그림 15 및 16에 표시된 것처럼 요소 인젝터를 통해 DragDropService 토큰을 자체 전역 싱글톤 인스턴스로 대체하라는 지침이 중첩됩니다. 현재 글로벌 싱글톤 DragDropService를 사용해야 하는 경우 구성 요소 라이브러리의 Draggable 명령어 Droppable 명령어가 지연 로드된 모듈 간에 통신할 수 있도록 이 두 가지 추가 명령어를 선언하고 내보내는 모듈만 도입하면 됩니다.

    지식 포인트 요약: 요소 인젝터는 모듈 인젝터보다 우선순위가 높습니다.

    3.5 사례 5: 로컬 테마 기능 시나리오에서 로컬 문제에 드롭다운 메뉴를 연결하는 방법

    DevUI 구성 요소 라이브러리의 테마는 CSS 사용자 정의 속성(css 변수)을 사용하여 다음을 선언합니다. css 변수 값 테마 전환을 달성하기 위해 루트를 사용합니다. 하나의 인터페이스에서 동시에 다양한 테마의 미리보기를 표시하려면 DOM 요소에서 로컬로 CSS 변수를 다시 선언하여 로컬 테마의 기능을 달성할 수 있습니다. 이전에 테마 디더 생성기를 만들 때 이 방법을 사용하여 로컬에 테마를 적용했습니다.

    1Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 17 로컬 테마 기능

    하지만 CSS 변수 값을 로컬에 적용하는 것만으로는 충분하지 않습니다. 기본적으로 본문 뒷면에 몇 가지 드롭다운 팝업 레이어가 붙어 있습니다. 그들의 부착 레이어는 지역 변수 외부에 있습니다. 이는 매우 당황스러운 문제로 이어질 것입니다. 로컬 테마 구성요소의 드롭다운 상자에는 외부 테마의 스타일이 표시됩니다.

    Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 18 부분 테마에서 외부 구성 요소에 첨부된 오버레이 드롭다운 상자 테마가 올바르지 않습니다.

    이때 어떻게 해야 합니까? 첨부 지점을 로컬 테마 돔 내부로 다시 이동해야 합니다.

    DevUI 컴포넌트 라이브러리의 DatePickerPro 컴포넌트의 Overlay는 Angular CDK의 Overlay를 사용하는 것으로 알려져 있습니다. 한 차례의 분석 후 다음과 같이 인젝션으로 대체했습니다.

    1) 먼저 OverlayContainer를 상속받아 구현합니다. 아래와 같이 ElementOverlayContainer를 소유합니다.

    2Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 19 ElementOverlayContainer 사용자 정의 및 _createContainer 로직 교체

    2) 그런 다음 미리 보기의 구성 요소 측에 새 ElementOverlayContainer를 직접 제공하고 새 오버레이가 OverlayContainer를 사용할 수 있도록 새 오버레이를 제공합니다. 원래 Overlay와 OverlayContainer는 루트에서 제공되지만 여기서는 이 두 가지를 다루어야 합니다.

    2Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 20 OverlayContainer를 사용자 정의 ElementOverlayContainer로 교체하고 새 오버레이 제공

    이제 미리보기 웹사이트로 이동하면 팝업 레이어의 DOM이 구성요소 미리보기 요소에 성공적으로 연결됩니다.

    2Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 21 cdk의 오버레이 컨테이너가 지정된 DOM에 연결되었으며 부분 테마 미리보기가 성공했습니다.

    일부 구성 요소 및 모달 상자 서랍 벤치에 대해 DevUI 구성 요소 라이브러리에 사용자 정의된 OverlayContainerRef도 있습니다. 그에 따라 교체를 조정해야 합니다. 마지막으로 팝업 레이어 및 기타 팝업 레이어를 구현하여 로컬 테마를 완벽하게 지원할 수 있습니다.

    지식 요약: 좋은 추상화 패턴은 모듈을 교체 가능하게 만들고 우아한 측면 프로그래밍을 달성할 수 있습니다.

    3.6 사례 6: CdkOverlay는 스크롤 막대에 CdkScrollable 명령을 추가해야 하지만 항목 구성 요소의 가장 바깥쪽 레이어에 추가할 수 없습니다.

    마지막 경우는 어떻게 처리하나요? , 덜 공식적인 방법에 대해 이야기하고 싶습니다. 공급자의 특성을 이해하는 것이 편리합니다. 공급자를 구성하는 것은 본질적으로 기존 인스턴스를 인스턴스화하거나 매핑하는 데 도움이 됩니다.

    cdkOverlay를 사용하는 경우 팝업 상자가 스크롤 막대를 따라가며 올바른 위치에 정지되도록 하려면 스크롤 막대에 cdkScrollable 명령을 추가해야 한다는 것을 알고 있습니다.

    이전 예시와 여전히 같은 장면입니다. 전체 페이지는 라우팅을 통해 로드됩니다. 단순화를 위해 구성 요소 호스트에 스크롤 막대를 작성했습니다.

    2Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 22 콘텐츠 오버플로 스크롤 막대가 Overflow:auto를 구성 요소:host

    에 기록합니다. 이런 식으로 모듈이 라우터 정의에 의해 지정됩니다. 즉, 표시되지 않습니다. 같은 방식으로 <app-theme-picker-customize></app-theme-picker-customize>를 호출합니다. cdkScrollable 명령어를 추가하는 방법은 무엇입니까? 해결 방법은 다음과 같습니다. 여기에는 일부 코드가 숨겨져 있고 핵심 코드만 남습니다.

    2Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 23 주입을 통해 인스턴스 생성 및 수동으로 라이프사이클 호출

    여기서 주입을 통해 cdkScrollable 인스턴스가 생성되고, 라이프사이클은 컴포넌트의 라이프사이클 단계에서 동기적으로 호출됩니다.

    이 솔루션은 형식적인 방법은 아니지만 문제를 해결하는 방법은 독자들이 맛볼 수 있는 아이디어와 탐구로 남겨두었습니다.

    지식 요약: 종속성 주입 구성 공급자는 인스턴스를 생성할 수 있지만 인스턴스는 일반 서비스 클래스로 취급되며 완전한 수명 주기를 가질 수 없다는 점에 유의하세요.

    3.7 더 많은 플레이 방법: 대체 플랫폼을 사용자 정의하여 터미널에서 실행되는 Angular 프레임워크의 상호 작용을 실현합니다.

    이 블로그 게시물을 참조할 수 있습니다: "Rendering Angular apps in Terminal"

    2Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)

    그림 24 교체 RendererFactory2 렌더러 및 기타 콘텐츠를 사용하면 Angular가 터미널에서 실행될 수 있습니다. 작성자는 Angular 애플리케이션이 터미널에서 실행될 수 있도록 RendererFactory2 및 기타 렌더러를 교체했습니다. 이것이 바로 Angular 디자인의 유연성입니다. 플랫폼도 교체할 수 있습니다. 강력하고 유연합니다. 자세한 교체 세부정보는 원본 기사에서 확인할 수 있으며 여기에서는 더 이상 설명하지 않습니다.

    지식 요약

    : 종속성 주입의 힘은 공급자가 자체적으로 이를 구성하고 최종적으로 대체 논리를 구현할 수 있다는 것입니다.

    4 요약

    이 기사에서는 제어 반전의 종속성 주입 모드와 그 이점을 소개합니다. Angular에서 종속성을 찾는 방법, 공급자를 구성하는 방법, 제한 및 필터링 데코레이터를 사용하여 원하는 것을 얻는 방법을 소개합니다. 결과는 N개의 사례를 통해 개발 및 프로그래밍에서 직면하는 문제를 해결하기 위해 종속성 주입의 지식 포인트를 결합하는 방법을 분석하는 데 추가로 사용됩니다.

    종속성 검색 프로세스를 올바르게 이해하면 정확한 위치(사례 1 및 2)에서 공급자를 구성하고, 다른 인스턴스를 싱글톤(사례 4 및 5)으로 대체할 수 있으며, 심지어 중첩된 구성 요소 패키지의 제한 사항도 넘을 수 있습니다. 제공된 예제(사례 3)를 따르거나 제공된 메서드 곡선을 사용하여 명령어 인스턴스화(사례 6)를 구현합니다.

    다섯 번째 경우는 간단한 교체인 것 같지만 교체 가능한 코드 구조를 작성하려면 주입 모드에 대한 심층적인 이해와 추상화가 아닌 경우 각 함수에 대한 더 좋고 합리적인 추상화가 필요합니다. 적절하다면 종속성 주입을 활용할 수 없습니다. 주입 모드는 모듈이 플러그형, 플러그인형 및 부품 기반이 될 수 있는 더 많은 공간을 제공하여 결합을 줄이고 유연성을 높여 모듈이 더욱 우아하고 조화롭게 함께 작동할 수 있도록 합니다.

    강력한 종속성 주입 기능은 구성 요소 통신 경로를 최적화할 수 있을 뿐만 아니라 더 중요한 것은 제어 반전을 달성하여 캡슐화된 구성 요소를 프로그래밍의 더 많은 측면에 노출할 수 있으며 일부 비즈니스별 논리 구현도 유연해질 수 있다는 것입니다.

    더 많은 프로그래밍 관련 지식을 보려면

    프로그래밍 비디오

    를 방문하세요! !

    위 내용은 Angular의 종속성 주입 패턴에 대한 심층적인 이해(플레이 사례)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제