검색 상자 인 하위 구성 요소가 있습니다. 사용자는 입력을 입력하고 검색 버튼을 누릅니다. 그러면 부모 컴포넌트가 검색 매개 변수를 사용하여 검색 서비스를 호출하고 그 결과를 하위 컴포넌트의 Observable 입력 속성에 할당하는 '검색'이벤트를 내 보냅니다. 하위 구성 요소 입력 속성의 설정자에서 Observable을 구독하고 결과를 매핑합니다. 내 문제는 마우스 이동 또는 단추 클릭과 같은 이벤트가 발생할 때까지 결과를 설정할 때 UI가 새로 고쳐지지 않는다는 것입니다. ngZone을 사용하여 구독을 요청해야한다고 생각합니다. 제 질문은 왜 이것을해야합니까? 내 검색 구성 요소의 대체 풍미에서 부모 구성 요소는 구독 호출에 대한 책임이 있으며 결과를 자식 구성 요소의 입력 속성에 할당하며 이는 예상대로 작동합니다. 이 두 가지 접근법과 해결 방법이 다른 점에 관해서는 약간의 설명을 정말 고맙게 생각합니다.각도 2 Observable 입력 구독 후 UI 업데이트 안 함
다음은 내 검색 상자 (하위) 구성 요소입니다.
import {
AfterViewInit, ChangeDetectorRef, ChangeDetectionStrategy, Component,
ElementRef, EventEmitter, Input, OnChanges,
Output, SimpleChanges, ViewChild } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
import {
ApplicationService, PromptActions, PromptType,
SearchItem, SearchItemType, SearchType, SearchArgs,
UserPromptRequest
} from '../../../core';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { PanelBarItemModel } from '@progress/kendo-angular-layout';
@Component({
moduleId: module.id,
selector: 'search-box',
templateUrl: 'search-box.component.html',
styleUrls: ['search-box.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SearchBoxComponent implements ControlValueAccessor {
constructor(private cd: ChangeDetectorRef, private applicationService: ApplicationService) { }
@Input() searchText: string;
@Output() search: EventEmitter<SearchArgs> = new EventEmitter();
private _searchObservable: Observable<SearchItemType[]>;
@Input()
set searchObservable(val: Observable<SearchItemType[]>) {
this._searchObservable = val;
if (this._searchObservable) {
this.searchSubscription = this._searchObservable.subscribe(r => this.resp(r));
}
}
private _selectedItem: SearchItem;
@Input()
set selectedItem(val: SearchItem) {
this._selectedItem = val;
this.propagateChange(this._selectedItem);
}
get selectedItem(): SearchItem {
return this._selectedItem;
}
searchResultsModel: PanelBarItemModel[];
private _searchResults: SearchItemType[];
@Input()
set searchResults(val: SearchItemType[]) {
this._searchResults = val;
this.setUpPanelBarModel();
}
get searchResults(): SearchItemType[] {
return this._searchResults;
}
private setUpPanelBarModel() {
this.isSearching = false;
this.cd.markForCheck();
}
onSearch() {
this.isResultsPopupVisible = true;
this.searchResults = undefined;
let searchArgs = new SearchArgs(this.searchText, this.selectedSearchTypeValue);
this.search.emit(searchArgs);
this.isSearching = true;
this.cd.markForCheck();
}
resp(r: any) {
this.searchResults = r;
this.cd.markForCheck();
}
writeValue(obj: any): void {
this.selectedItem = obj;
}
private propagateChange = (_: any) => { };
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void { } // Don't need
}
아래는 상위 구성 요소 코드입니다. onSearch에서 주석 처리되고 주석 처리되지 않은 행을 교체하면 즉시 결과가 표시됩니다. 그렇지 않으면 마우스를 움직이거나 클릭하거나 키를 눌러 다른 각도 UI 눈금을 트리거해야합니다. 어떤 도움을 많이 주셔서 감사합니다!
import { ChangeDetectorRef, ChangeDetectionStrategy, Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { SettingsEntityListComponentBase } from '../../component-bases';
import { ClientType } from '../../models/ClientType';
import { ClientTypeService } from '../../services/client-type.service'
import {
ApplicationService, NotificationContext,
Permission, UserService, WindowType, SearchArgs,
SearchItem, SearchItemType, SearchTypeValues
} from '../../../core';
@Component({
moduleId: module.id,
selector: 'client-type-list',
templateUrl: 'client-type-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ClientTypeListComponent extends SettingsEntityListComponentBase<ClientType> {
constructor(
changeDetector: ChangeDetectorRef,
appService: ApplicationService,
clientTypeService: ClientTypeService,
userService: UserService) {
super(changeDetector, appService, clientTypeService, userService, Permission.SettingsClientTypes,
Permission.GlobalClientTypes, WindowType.ClientTypeDetail, NotificationContext.ClientTypeChanged);
}
searchText: string = '4455';
selectedSecurity: SearchItem;
searchObservable: Observable<SearchItemType[]>;
searchResults: SearchItemType[];
onSearch(args: SearchArgs): void {
this.searchObservable = this.appService.search(args.searchText, SearchTypeValues.Securities);
//this.appService.search(args.searchText, SearchTypeValues.Securities).subscribe(r => this.resp(r));
}
resp(r: any) {
this.searchResults = r;
this.changeDetector.markForCheck();
}
}