0

Clickイベントの後、Angular2はChangeDetectionをトリガしません。以下のコードスニペットは、あるコンポーネントから別のコンポーネントにデータを取得することです。クリック後にAngular2火災の変化を検出しない

onClickEvent

(click)="$event.preventDefault(); setApartmentObject(FlatObject)"; 

ApartmentOverviewComponent

constructor(private _apart:ApartmentService) {} 

setApartmentObject(flat:ApartmentObject) { 
    this._apart.setApartmentDetails(flat); 
} 

ApartmentService

Injectable() 
export class ApartmentService { 

    apartmentDetails:ApartmentObject 

    getApartmentDetails():Observable<ApartmentObject> { 
     return Observable.create((observer) => { 
      observer.next(this.apartmentDetails); 
      observer.complete(); 
     }); 
    } 

    setApartmentDetails(value:ApartmentObject) { 
     this.apartmentDetails = value; 
    } 
} 

ApartmentDetailComponent

constructor(private _apart:ApartmentService) 

get apartmentDetails() { 
    this._apart.getApartmentDetails().subscribe(data => { 
     this._apartmentDetails = data; 
    }); 
    return this._apartmentDetails; 
} 
HTMLファイルで

<p><strong>{{apartmentDetails.name || 'Musterwohnung'}}</strong></p> 

また、私は成功せず、持つEventEmitterでこの問題を解決しようとしました。次の汚れた修正のみが動作します:

constructor(private _ref:ChangeDetectorRef) { 
    this._ref.detach(); 
    setInterval(() => { 
    this._ref.detectChanges(); 
    }, 300); 
} 
+0

私は問題を理解していません。 Angular runが検出を変更していて、それを防止したいのですか、または変更検出を実行しますがAngularは実行しませんか? –

+0

何が起こると思いますか?なぜあなたはAngular2が変更検出を実行しないと思いますか? –

+0

問題はangleがApartmentDetailComponentのApartmentOverviewComponentの1つのオブジェクトからデータをロードし、実際のデータで再レンダリングする必要があることです。私は、ApartmentDetailComponentのデータを取得しますが、changeDetectionはトリガーしないので、ビューは再レンダリングしません。そしてなぜ私は知りません。 – Zero

答えて

2

実際に値が読み取られないようにするコードにはいくつかの問題があります。

まず、あなたのサービスでは、値を設定するときに、オブザーバブルオブジェクトに与えるのではなく、サービスのインスタンス上で行うだけです。 observableは値が変更されたことを知ることができないので、change(next)イベントを送出しません。このため、ApartmentOverviewComponent. setApartmentObject()は何もしません。観測データに実際にデータを供給するには、Subjectを使用する必要があります。

ApartmentDetailComponentでは、この単純なシナリオ(データは常に同期的に提供されます)では、試してみる価値があります。しかし、前述したように、データは変わることはありません。また、コンポーネントのインスタンスの_apartmentDetailsフィールドにデータを格納する針です。あなたはあなたのテンプレートにオブザーバブルを使うことができます。

作業実装はそのようなものです:

@Injectable() 
class ApartmentService { 
    // BehaviorSubject is a type of an Observable that can be manually fed with data 
    // and returns it's last value to any subscriber. 
    apartmentDetails = new BehaviorSubject<ApartmentObject>({name: 'Musterwohnung'}); 

    // Instead of using a property of the service, just inform the 
    // subject about knew data and let it spread the change for you. 
    setApartmentDetails(value: ApartmentObject) { 
    this.apartmentDetails.next(value); 
    } 
} 

@Component({ 
    selector: 'overview-cmp', 
    // Side note: you don't need to .preventDefault() here. 
    template: `<a (click)="setApartmentObject({name: 'Shiny Aparament'})">click</a>` 
}) 
class ApartmentOverviewComponent { 
    constructor(private apartService: ApartmentService) {} 

    // Works same as before. 
    setApartmentObject(flat: ApartmentObject) { 
    this.apartService.setApartmentDetails(flat); 
    } 
} 

@Component({ 
    selector: 'details-cmp', 
    // Use the 'async' pipe to access the data stored in an Observable 
    // object. Also, to secure the code, use '?' to safely access the property. 
    template: `<p><strong>{{(details | async)?.name}}</strong></p>` 
}) 
class Apartament { 
    // This is the observable with data. 
    details: Observable<ApartmentObject>; 

    constructor(private apartService: ApartmentService) {} 

    // When component initialises, assign the observable data from the service 
    ngOnInit() { 
    this.details = this.apartService.apartmentDetails; 
    } 
} 
+0

ありがとうございました!それは動作します! – Zero

関連する問題