2017-10-17 114 views
2

通用

我遇到問題。沒有調用changeDetectorRef.markForCheck方法,我的組件不會重新渲染。爲什麼沒有`changeDetectorRef.markForCheck`,組件沒有檢測到內部狀態改變?

我有一個自動完成。當輸入發生變化時,我發送一些異步請求(只需簡單的HttpClient服務和get方法)。之後,我填寫一些內部狀態。

該代碼

注意markForCheck調用。如果我刪除這條線:沒有任何工作。我注意到,如果我刪除它,並且如果在組件外部單擊某處,我會看到重新渲染。正確的時候,我點擊某處組件重新呈現。

順便說一句,我意識到markForCheck是偶然工作。我只是嘗試了一些,它的工作。我從一些文章中獲得關於CD機制和CD服務的信息。

這是我的主要成分:

@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):

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

這些都只是片段。整個代碼在GitHub上可用。

順便說,我有另一種組分(選定代碼塊),我有輸入showLoader在它。它有完全相同的問題。

我的想法

可能問題以某種方式連接到區域機制。從我知道的一些文章中,那個zone.js猴子會修補一些事件或XHR電話。而我的情況是XHR調用(我沒有深入HttpClient,但它只能進行HTTP調用)。

我想

我想知道爲什麼更改未檢測出盒子裏有什麼(所以我會用markForCheck,我會確定)我想找到我的代碼錯誤。

希望你能幫助我。

回答

1

這是由於在父組件上添加了ChangeDetectionStrategy.OnPush。

在該父項中,如果其輸入的引用不更改,則不會檢查其子樹組件是否更改。

+0

是否默認設置OnPush?我沒有設置它。 –

+0

這是很好的變體,我在想它。由於它沒有設置,我確定它是變化檢測策略。 –

+0

你如何解釋? –

相關問題