2017-10-17 13 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

    あなたはそれをどのように説明できますか? –

    関連する問題