我订阅了Angular中的一个主题,在价值变化时,我试图改变组件中的变量值。在控制台中,该值显示更新,但在视图(HTML)上,它不显示。
Service.ts
export class GMapsService {
public mysubject: Subject<any> = new Subject();
getData(or, des) {
var origin1 = or;
var destinationA = des;
var service = new google.maps.DistanceMatrixService();
var self = this;
service.getDistanceMatrix(
{
origins: [origin1],
destinations: [destinationA],
travelMode: 'DRIVING',
avoidHighways: false,
avoidTolls: true,
},
(response, status) => {
// this.mysubject.next(response);
setInterval(
function () {
self.mysubject.next(Math.random())
},
2000
)
}
);
}
}
app.component.ts
export class AppComponent implements OnInit {
title: any = 'app';
constructor(private GMapsService: GMapsService) { }
ngOnInit() {
this.GMapsService.getData('dallas, tx', 'austin, tx');
this.GMapsService.mysubject.subscribe((value) => {
this.title = value;
console.log(this.title);
//title is random number in console. ex: 0.4333333
//title is still 'app' on view till now.
});
setTimeout(() => {
console.log(this.title);
}, 5000);
//title is random number in console. ex: 0.4333333
// title suddenly become 'random number ex: 0.4333333' on view after it is logged after 5 secs. How does logging 'title' again after 5 seconds change its value?
}
}
app.component.html
{{title}}
我相信,如果控制台中的相同值发生变化,它也应该反映在视图部分。在其他问题上,它说,我错过了这个上下文,但是值在控制台中得到了更新,所以我相信我不会错过上下文。
编辑:我尝试在5秒后记录标题,并且视图上突然发生变化。如何记录值可以在视图上更改它?
答案 0 :(得分:2)
由于您使用的是基本主题,因此您需要在从同步调用接收数据之前订阅主题(除非您嘲笑它,否则不应使用getDistanceMatrix)。也就是说,因为默认情况下基本主题不会重播最后发布的值。
如果您想避免这种情况,可以使用ReplaySubject或BehaviorSubject:
service.ts
@Injectable()
export class GMapsService {
public mysubject: ReplaySubject<any> = new ReplaySubject(1);
getData(or, des) {
var origin1 = or;
var destinationA = des;
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin1],
destinations: [destinationA],
travelMode: 'DRIVING',
avoidHighways: false,
avoidTolls: true,
},
(response, status) => {
console.log('service callback');
this.mysubject.next(response);
}
);
}
}
component.ts
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
title: any = 'app';
constructor(private GMapsService: GMapsService, private changeDetectorRef: ChangeDetectorRef) { }
ngOnInit() {
this.GMapsService.getData('dallas, tx', 'austin, tx');
this.GMapsService.mysubject.subscribe((value) => {
this.title = value;
this.changeDetectorRef.detectChanges();
});
}
}
工作示例here
编辑:显然,Google DistanceMatrixService.getDistanceMatrix
响应并未触发更改检测。尝试使用ChangeDetectorRef
并手动查找更改。我相应地更改了代码示例。
ADDENDUM:Angular使用一个更改检测系统,该系统挂钩到异步事件的典型触发器,以检测视图的哪些部分必须更新。触发器的示例是用户输入,计时器(setTimeout,setInterval)或Websocket事件。如果Google DistanceMatrixService使用某种方法来检索不会触发角度更改检测系统的数据,则不会检查视图的数据是否有更改,因此无法正确更新。由于setTimeout
会触发更改检测,因此在您使用setTimeout
时它会正常工作。您可以阅读有关角度变化检测系统here的更多信息。