기본 뷰 모델: Angular2를 사용한 간단한 구성 요소 아키텍처 워크플로

참고: 이것은 내가 Angular lolol을 처음 배우기 시작했을 때 찾았으면 하는 문서입니다.

목표


  • 템플릿에서 데이터베이스 개체의 전체 목록을 표시합니다(예: 블로그 게시물)
  • 모든 객체의 중첩 배열에 대한 검색을 완료하여 목록을 필터링합니다(예: 태그 또는 범주 하위 목록으로 필터링)
  • .
  • 모든 비즈니스 및 데이터 로직이 완전히 분리되었는지 확인합니다
  • .

    실행 워크플로



    이것이 제가 찾은 최선의 방법입니다.

  • 일반 로직: 데이터 소스에서 템플릿으로 데이터 가져오기

  • 조건부 보기 논리: 데이터가 다양한 방식으로 표시되는 방식을 보여주는 보기 구성(데이터 논리와 별개)

  • 사용자 제어 로직 및 효과: 데이터 소스와 상호 작용하는 보기 모델 로직을 추가합니다
  • .

    건너뛰기



  • General Logic: Data to Template List
  • Data Structure in Interface
  • Getting Data from Service into Component File
  • Getting Data from the Component Template


  • Conditional View Logic: Toggle User Views
  • Adding Conditional Variables to the Template
  • Binding to the Component Itself


  • User Controls and Logic Effects
  • Template: User Control Binds the searchText Property
  • Apply searchString Against Nested Array


  • 일반 논리: 데이터를 템플릿 목록으로


    인터페이스의 데이터 구조



    데이터 배열의 개체를 게시물이라고 합니다. 이것은 [인터페이스를 나타내기 위해 "I"접두사 규칙을 사용하여] 유형을 정의하는 인터페이스입니다.

    // post.interface.ts
    export interface IPost {  
      id: string | number;  
      title: string;  
      body?: string;  
      cover?: string;  
      tags?: string[]; // <-- this is what we need to filter later.
    }
    


    서비스에서 구성 요소 파일로 데이터 가져오기



    데이터를 템플릿에 바인딩하기 위해 post라는 새로운 빈 배열(IPost[] 유형)을 postService의 getPosts() 메서드에서 구독한 데이터로 채웁니다.

    // post-list.component.ts
    
    import { Component, OnInit } from '@angular/core';
    import { PostService } from '../../services/post-service';
    
    @Component({  
      selector: 'app-post-list',  
      templateUrl: './post-list.component.html',  
      styleUrls: ['./post-list.component.scss']
    })
    
    export class PostListComponent implements OnInit {
      posts: IPost[]; // Initialize an empty array to the type of IPost[]  
    
      constructor(private postService: PostService) {}  
    
    /*    When this component initializes, we access the data from the service's get method
    and assign the stream of data to the empty posts array        */  
    
      ngOnInit(): void {     
        this.postService.getPosts().subscribe(res => {       
        this.posts = res;    
        });
      }   
    }
    


    구성 요소 템플릿에서 데이터 가져오기



    각도의 텍스트 보간을 사용하여 *ngFor 지시문을 통해 반복 가능한 요소에 게시물 데이터를 추가합니다.

    <div *ngFor="let post of posts">  
      <div class="single-post">    
        {{ post.cover }}
        {{ post.title }}
        {{ post.tags }}  
      </div>
    </div>
    
    



    조건부 보기 논리: 사용자 보기 전환



    템플릿에 조건부 변수 추가



    사용자에게 게시물의 전체 목록을 표시하기 위해(구성 요소의 코드에 너무 많이 추가하지 않고도) 완전히 다른 목록으로 전환하는 조건부 지시문을 사용할 수 있습니다. 이것은 *ngIf/else 지시문을 사용하여 수행되며 특정 조건이 충족되면 [이 경우 searchText 속성이 비어 있는 경우] 요소를 표시하도록 앱에 지시하고, 그렇지 않으면 완전히 별개의 요소를 표시하도록 지시할 수 있습니다.

    <!--Show this div if the searchText string is empty-->
    <ng-container 
      *ngIf="searchText == '';else filteredListTemplate">  
      <div *ngFor="let post of posts">    
        <div class="single-post">      
          {{ post.cover }}
          {{ post.title }}
          {{ post.tags }}
        </div>
      </div>
    </ng-container>
    
    <!--Show this div as an alternative -->
    <ng-template 
      #filteredListTemplate>
      <!--Notice that 'let post of posts' is now 'let post of filteredPosts'-->  
      <div
        *ngFor="let post of filteredPosts">    
        <div class="single-post">
          {{ post.cover }}
          {{ post.title }}
          {{ post.tags }}
        </div>
      </div>
    </ng-template>
    


    구성 요소 자체에 바인딩


  • 이제 템플릿에서 참조한 FilteredPosts 속성이 구성 요소 자체에 존재하고 IPost[] 유형으로 지정해야 합니다. 이렇게 하면 필터링된 게시물만 FilteredPosts 배열로 반환하는 함수를 실행할 수 있습니다.
  • 그런 다음 문자열 유형에 searchText 속성을 추가하여 데이터를 필터링하는 동시에 바인딩할 항목을 확보합니다.

  • export class PostListComponent implements OnInit {  
    posts: IPost[];  
    filteredPosts: IPost[]; // <-- new array to gather filtered posts    
    searchText = ''; // <-- needs to be empty to show the 'all' list of posts
    
    constructor(private postService: PostService) {}    
    
    ngOnInit(): void {    
      this.postService.getPosts().subscribe(res => {      
        this.posts = res;
        }  
      }
    }
    



    사용자 컨트롤 및 논리 효과



    템플릿: 사용자 컨트롤은 searchText 속성을 바인딩합니다.



    이제 searchText 문자열을 검색 키워드로 채우려고 합니다. 이를 수행하는 한 가지 방법은 특정 문자열을 통과하는 기능이 있는 클릭 이벤트를 추가하는 것입니다.
    filterPosts() 메서드(아래 문자열을 통과하는 것을 볼 수 있음)는 다음 구성 요소 섹션에 포함됩니다.

    <button (click)="filterPosts('science')">
      Science
    </button>
    
    <button (click)="filterPosts('cooking')">  
      Cooking
    </button>
    
    <ng-container
      *ngIf="searchText == '';else filteredListTemplate">  
      <div *ngFor="let post of posts">
        <div class="single-post">
          {{ post.cover }}      
          {{ post.title }}      
          {{ post.tags }}    
        </div>  
      </div>
    </ng-container>
    
    <ng-template
      #filteredListTemplate>  
      <div *ngFor="let post of filteredPosts">    
        <div class="single-post">
          {{ post.cover }}      
          {{ post.title }}      
          {{ post.tags }}    
        </div>  
      </div>
    </ng-template>
    


    중첩 배열에 대해 searchString 적용



    filter() 메서드는 경쟁 배열을 반환하므로 반환된 데이터에 includes() 메서드를 적용합니다.

    export class PostListComponent implements OnInit {
    posts: IPost[];
    filteredPosts: IPost[];
    searchText = '';    
    
    constructor(private postService: PostService) {}    
    
    ngOnInit(): void {    
      this.postService.getPosts().subscribe(res => {      
        this.posts = res;    
      }  
    }
    
    filterPosts(tagStr: string): any {    
      this.searchText = tagStr; // bind searchText property to passed string    
      this.searchText = this.searchText.toLowerCase(); // make lowercase to avoid errors        
      this.filteredPosts = this.posts.filter(eachPost => {      
        const tagsArr = eachPost['tags'] // We access the nested array      
        const arrString = String(tagsArr).toLowerCase(); // convert object to string      
        if (eachPost && tagsArr) {            
          return arrString.includes(this.searchText);      
          }    
        });  
      }        
    }
    
    



    그게 다야. 그게 다야.



    우리는 다음을 이해함으로써 논리의 분리를 통해 생각하는 방법을 이해했습니다.
  • 특정 데이터 메서드는 해당 서비스/제공자에 남아 있으며 뷰 모델에서 필요할 때 호출합니다
  • .
  • 프로그래밍 논리로 구성 요소를 오버로드하는 대신 Angular의 템플릿 기반 기능(지시문 등)을 활용하면 리팩토링이 필요한 경우 완전히 중단됩니다. 결국, html 템플릿을 추출하는 것은 구성 요소의 클래스를 리팩터링하는 것보다 훨씬 덜 위험합니다(다른 구성 요소 로직에 예측할 수 없는 방식으로 엮일 수 있음)
  • .

    리아

    좋은 웹페이지 즐겨찾기