我有一个示例角度应用程序,其中包含一项服务和一个组件:
Service:
export class SseService {
private eventSource = new EventSource('http://localhost:8080/events');
private message = signal('default value');
getMessageSignal(): Signal<string> {
return this.message.asReadonly();
}
constructor() {
this.eventSource.onmessage = event => {
console.log('Received event: ', event);
this.message.set(event.data as string);
};
}
}`
Component:
`@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
title = 'frontend';
sseService = inject(SseService);
messageSignal = this.sseService.getMessageSignal();
// printMessage = effect(() => console.log(this.message())); //If I uncomment this line, the messageSignal does update in my html
}
<body>
<p>{{messageSignal()}}</p>
</body>
问题是,如果我没有带有effect()的行,我的messageSignal就不会更新
因为
EventSource
没有被Zone.js
捕获。
尝试这个(在服务构造函数中注入NgZone):
export class SseService {
private eventSource = new EventSource('http://localhost:8080/events');
private message = signal('default value');
getMessageSignal(): Signal<string> {
return this.message.asReadonly();
}
constructor(private ngZone: NgZone) {
this.eventSource.onmessage = event => {
console.log('Received event: ', event);
// this.message.set(event.data as string);
this.ngZone.run(() => this.message.set(event.data as string));
};
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
title = 'frontend';
sseService = inject(SseService);
messageSignal = this.sseService.getMessageSignal();
// printMessage = effect(() => console.log(this.message())); //If I uncomment this line, the messageSignal does update in my html
}
<body>
<p>{{messageSignal()}}</p>
</body>