单击后 Angular2 不要触发 changeDetection
Angular2 dont fire changeDetection after click
Angular2 在单击事件后不会触发 ChangeDetection
。下面的代码片段是将数据从一个组件获取到另一个组件。
onClickEvent
(click)="$event.preventDefault(); setApartmentObject(FlatObject)";
ApartmentOverviewComponent
constructor(private _apart:ApartmentService) {}
setApartmentObject(flat:ApartmentObject) {
this._apart.setApartmentDetails(flat);
}
公寓服务
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>
我也尝试用事件发射器解决这个问题,但没有成功。只有以下脏修复有效:
constructor(private _ref:ChangeDetectorRef) {
this._ref.detach();
setInterval(() => {
this._ref.detectChanges();
}, 300);
}
您的代码存在一些问题,实际上阻止了读取值。
首先——在你的服务中——当你设置值时,你只是在服务的实例上进行,而不是将它提供给可观察对象。 observable 只是不知道值已经改变,所以它不会发出 change (next) 事件。这就是 ApartmentOverviewComponent. setApartmentObject()
什么都不做的原因。要实际向 observable 提供数据,您需要使用 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;
}
}
Angular2 在单击事件后不会触发 ChangeDetection
。下面的代码片段是将数据从一个组件获取到另一个组件。
onClickEvent
(click)="$event.preventDefault(); setApartmentObject(FlatObject)";
ApartmentOverviewComponent
constructor(private _apart:ApartmentService) {}
setApartmentObject(flat:ApartmentObject) {
this._apart.setApartmentDetails(flat);
}
公寓服务
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>
我也尝试用事件发射器解决这个问题,但没有成功。只有以下脏修复有效:
constructor(private _ref:ChangeDetectorRef) {
this._ref.detach();
setInterval(() => {
this._ref.detectChanges();
}, 300);
}
您的代码存在一些问题,实际上阻止了读取值。
首先——在你的服务中——当你设置值时,你只是在服务的实例上进行,而不是将它提供给可观察对象。 observable 只是不知道值已经改变,所以它不会发出 change (next) 事件。这就是 ApartmentOverviewComponent. setApartmentObject()
什么都不做的原因。要实际向 observable 提供数据,您需要使用 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;
}
}