Angular 信号不更新 html 模板

问题描述 投票:0回答:1

我有一个示例角度应用程序,其中包含一项服务和一个组件:

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就不会更新

angular signals angular17
1个回答
0
投票

因为

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>
© www.soinside.com 2019 - 2024. All rights reserved.