2017-10-17 11 views
2

일반

문제가 있습니다. 내 구성 요소가 changeDetectorRef.markForCheck 메서드를 호출하지 않고 다시 렌더링하지 않습니다.왜 구성 요소가`changeDetetectorRef.markForCheck`없이 내부 상태 변경을 감지하지 못합니까?

나는 자동 완성 기능을 가지고 있습니다. 입력이 변경되면 비동기 요청 (단순한 HttpClient 서비스 및 get 메소드)을 보냅니다. 그 후, 나는 내부 상태를 채 웁니다.

코드

markForCheck 전화. 이 행을 삭제하면 아무 효과가 없습니다. 만약 내가 그것을 제거하고 내가 어딘가에 구성 요소의 외부를 클릭하면, 내가 다시 렌더링을 볼 것으로 나타났습니다. 클릭하면 어딘가에 컴포넌트가 다시 렌더링됩니다.

그런데 우연히 markForCheck이 작동하고 있다는 것을 깨달았습니다. 방금 시도한 것이 작동했습니다. 일부 기사에서 CD 메커니즘 및 CD 서비스에 대한 정보를 얻었습니다.

@Component({ 
    selector: 'tags-internal-auto-complete-results', 
    template: ` 
    <div class="container"> 
     <span *ngFor="let tag of data" (click)="selectTag.emit(tag);" class="tag"> 
     {{tag.name}} 
     </span> 
    </div> 
    `, 
    styleUrls: ['./results.styles.css'], 
}) 
export class TagsAutoCompleteResultsComponent { 
    @Input() data: Tag[] = []; 

    @Output() selectTag = new EventEmitter<Tag>(); 
} 

이 그냥 조각입니다 :

@Component({ 
    selector: 'tags-auto-complete', 
    template: ` 
    <tags-internal-auto-complete-input 
     // .... 
     (inputChanged)="onInputChange($event);" 
    ></tags-internal-auto-complete-input> 
    <tags-internal-auto-complete-results 
     [data]="queryResultsTags" 
     // .... 
    ></tags-internal-auto-complete-results> 
    `, 
}) 
export class TagsAutoCompleteContainerComponent implements OnInit { 
    inputChanged = new Subject<string>(); 
    queryResultsTags: Tag[] = []; 

    constructor(
    private tagsService: TagsService, 
    private changeDetectorRef: ChangeDetectorRef, 
) {} 

    onInputChange(query: string): void { 
    this.inputChanged.next(query); 
    } 
    ngOnInit() { 
    this.inputChanged 
     .filter(inputValue => inputValue.length > 0) 
     .debounceTime(400) 
     .switchMap(query => this.tagsService.getTagsList({ query })) 
     .do(() => this.changeDetectorRef.markForCheck()); // note this 
     .subscribe((tags: Tag[]) => (this.queryResultsTags = tags)) // here I change the input of inner component 
    } 
    // ... 

여기 하위 구성 요소 (tags-internal-auto-complete-results)입니다 :

여기 내 주요 구성 요소입니다. 전체 코드는 GitHub에서 사용할 수 있습니다. 그런데

  • inner component
  • main component

    • , I는 다른 구성 요소 (태그 선택된 블록)을 가지고 있고 그 안에 입력 showLoader있다. 똑같은 문제가 있습니다.

      내 생각 아마 문제가 어떻게 든 영역 메커니즘에 연결

      . 내가 아는 몇 가지 기사에서, 해당 zone.js 원숭이 - 일부 이벤트 또는 XHR 호출을 패치합니다. 그리고 제 경우는 XHR 호출입니다 (나는 HttpClient에 깊이 들어가지는 않았지만 HTTP 호출 만 만들어야 함).

      나는 변화가 상자 밖으로 감지되지 않는 이유를 이해 할

      을 원하는 내가 내 코드에서 실수를 찾으려면 또는 (그래서 markForCheck를 사용하고 난 괜찮을 것입니다).

      희망을 보내 주시면 도와 드리겠습니다.

    답변

    1

    상위 구성 요소에 ChangeDetectionStrategy.OnPush가 추가 된 것이 원인입니다.

    해당 상위 항목에서 입력 내용의 참조가 변경되지 않으면 하위 트리 구성 요소가 변경되었는지 확인되지 않습니다.

    +0

    OnPush는 기본적으로 설정되어 있습니까? 나는 그것을 설정하지 않았다. –

    +0

    좋은 변종이고 그것에 대해 생각하고있었습니다. 설정되지 않았으므로 변경 감지 전략이라고 확신합니다. –

    +0

    어떻게 설명 할 수 있습니까? –