보기 모드 - 각도 디자인 모드

보기 모드는 일종의 전단 디자인 모드다.보기 모드는 비동기 요청 상태에 대응하는 보기를 자동으로 주입하는 방법이다.예를 들어 HTTP가 검색을 요청한 데이터에 의존하는 구성 요소는 로드 상태로 시작하여 홈 뷰나 오류 뷰로 전환될 해결 상태(오류 또는 성공)에 따라 달라집니다.
웹 프런트엔드 개발자라면 비동기 요청을 처리할 때 로더를 표시하고 홈 보기로 전환하거나 오류를 표시하는 중복된 UI 모드를 인식할 수 있습니다.개인적으로, 나는 매 페이지에 여러 개의 구성 요소가 있는 한 페이지 프로그램에서 독립적으로 불러온 코드가 중복되는 것을 알아차렸다.더 심각한 것은 템플릿이 부족하다는 지시를 받지 못했다는 것이다. (만약 내가 오류 처리기나 불러오는 프로그램을 잊어버리면.)
이 단문에서, 나는 코드의 중복을 줄이고 잃어버린 부분을 알리기 위해 나의 '보기 모드' 솔루션을 공유할 것이다.

뷰 모드의 View보기 모드를 다시 사용할 수 있는 목표를 실현하기 위해서 우리는 먼저 인터페이스를 정의하여 View 상태를 저장해야 한다.이런 보기 상태는 어떤 복잡성이 있을 수 있지만 본고에서 다음과 같은 상태를 중점적으로 소개할 것이다.
로드 - 비동기 요청 해결 전의 상태입니다.이 상태는 템플릿Loader에 주입됩니다.
데이터 - 응답(성공) 후 표시 데이터는 main 템플릿에 매핑됩니다.
오류 - 요청이 실패하면 오류 상태는 실패 원인과 error 템플릿에 대한 설명을 포함합니다.
export class View<T> {
  data?: T; // Store component data (of generic type T)
  loader?: boolean; // Whether to show the loader
  error?: Error;
}
이 구체적인 실현에서 나는 RxJS Observables를 사용하여 비동기 이벤트와 조작 흐름을 처리할 것이다.
주 이벤트 발사기에 나타난 모든 이벤트에 대해 우리는 View 상태로 포장한다.http는 가장 많이 사용되는 관찰 대상이기 때문에 우리는 그것을 예로 사용할 것이다. const view$: Observable<View<T>> = this.httpClient<T>(<url>)우리는 startWith에 적재 상태를 보낼 것이다.그리고 응답 이벤트 (데이터 T 를 받았을 때 mapView<T> 로 보낼 것입니다.처리 오류에 대해 catchError를 추가합니다.
const request$: Observable<View<T>> = this.httpClient<T>(<url>).pipe(
  startWith({loader: true}),
  map(response => ({data: response})),
  catchError(error => of({error})));
참고:
  • T 응답 유형
  • 의 자리 표시자

    뷰 모드 뷰 컨테이너ViewContainer는 주어진 보기에 정확한 템플릿을 주입하는 것을 책임진다.이 강좌에서, 우리는 structural 명령을 예로 사용할 것이다.
    사용법은 다음과 같습니다.
    <div *viewContainer="view$ | async;
                              main mainTmp;
                              error errorTmp;
                              loading loaderTmp">
    <div>
    
    <ng-template #mainTmp>...</ng-template>
    <ng-template #errorTmp>...</ng-template>
    <ng-template #loaderTmp>...</ng-template>
    
    <view-container
      *ngIf="view$ | async as view"
      [appViewMain]="mainTmp"
      [errorTmp]="errorTmp"
      [loaderTmp]="loaderTmp"
      [view]="view">
    </view-container>
    
    <ng-template #mainTmp>...</ng-template>
    <ng-template #errorTmp>...</ng-template>
    <ng-template #loaderTmp>...</ng-template>
    
    다음 부분에서 우리는 이 구조 지령을 실시할 것이다.그러나 그것도 하나의 구성 요소일 수 있다.만약 당신이 흥미가 있다면, 당신은 찾을 수 있습니다 full implementations.
    viewContainer 실행
    우선, 우리들은 우리의 지령을 창설할 것이다
    @Directive({ selector: '[viewContainer]' })
    export class ViewContainerDirective<T> implements AfterViewInit {
    
       ngAfterViewInit(): void {
           // Verify all the templates defined, throw an error otherwise 
       }
    }
    
    다음에 인용 템플릿을 저장할 속성을 정의합니다
      private _mainTemplateRef: TemplateRef<AppViewContext<T>> = null;
      private _errorTemplateRef: TemplateRef<AppViewContext<T>> = null;
      private _loaderTemplateRef: TemplateRef<AppViewContext<T>> = null;
    
    템플릿 인용 ((#<name> 을 속성에 귀속시킵니다.
    @Input() set viewContainerMain(templateRef: TemplateRef<any>) {
        this._mainTemplateRef = templateRef;
    }
    
    @Input() set viewContainerError(templateRef: TemplateRef<any>) {
        this._errorTemplateRef = templateRef;
    }
    
    @Input() set viewContainerLoading(templateRef: TemplateRef<any>) {
        this._loaderTemplateRef = templateRef;
    }
    
    
    이 귀속이 어떻게 작동하는지 알고 싶으면 microsyntax for directives를 보십시오.간단히 말하면 setter 이름은 명령어 이름 (접두사) 과 속성 이름 (접두사) 의 조합이다.
    이제 다시 ngAfterViewInit로 돌아가서 템플릿이 없는지 확인합니다.
      ngAfterViewInit(): void {
        if (!this._errorTemplateRef) throw new Error('View Pattern: Missing Error Template')
        if (!this._loaderTemplateRef) throw new Error('View Pattern: Missing Loader Template')
        if (!this._mainTemplateRef) throw new Error('View Pattern: Missing Main Template')
      }
    
    마지막으로, 매번 변경 View 할 때마다 템플릿을 용기에 삽입합니다.이를 위해 우리는 createEmbeddedViewAPI를 사용할 수 있기 때문에 ViewContainerRef 서비스를 주입할 수 있습니다.
    constructor(private _viewContainer: ViewContainerRef) { }
    
    createEmbeddedView개의 선택할 수 있는 매개 변수 중 하나는 상하문이다.상하문에 접근할 수 있는 데이터 (T - View<T> 를 제공합니다.
    private _context: AppViewContext<T> = new AppViewContext<T>();
    
    이제 setter를 실현하는 데 필요한 모든 것이 생겼습니다.
    @Input() set viewContainer(view: View<T>) {
        if (!view) return;
    
        this._context.$implicit = view; // setting view to be avilable in the template
        this._viewContainer.clear(); // Clears the old template before setting the the new one.
    
        if (view.loader)
          this._viewContainer.createEmbeddedView(this._loaderTemplateRef, this._context);
    
        if (view.error && !view.loader) // Defines the conditions to display each template in single place
          this._viewContainer.createEmbeddedView(this._errorTemplateRef, this._context);
    
        if (view.data && !view.error) 
          this._viewContainer.createEmbeddedView(this._mainTemplateRef, this._context);
      }
    

    마무리
    이 강좌에서 우리는 '보기 모드' 를 실현했다. 중복된 코드를 줄이고 템플릿을 편평하게 해서 구성 요소를 간소화할 수 있다.또한 일부 내용이 부족할 때 피드백을 받아 잠재적인 오류가 발생할 기회를 줄인다.
    이 모드는 제공mock dataloader를 통해 포장을 풀면 바로 사용할 수 있는 뼈대 로더를 지원하도록 쉽게 확장할 수 있습니다.You can check the full code and examples on Github .

    좋은 웹페이지 즐겨찾기