[英]BehaviorSubject doesn't execute when the variable changes
I am not sure if I understand the usage of a BehaviorSubject
, but what I want to do is watch a variable for change, and this variable is a two-way binding variable attached to <input type="file">
.我不确定我是否理解
BehaviorSubject
的用法,但我想要做的是观察一个变量的变化,这个变量是一个附加到<input type="file">
的双向绑定变量。 When the input changes I want to execute a function that will automatically upload the file.当输入更改时,我想执行一个自动上传文件的函数。
<input type="file" [(ngModel)]="presentationService.fileSelected">
The component I am using looks like this:我正在使用的组件如下所示:
@Component({
selector: '...',
templateUrl: '...'
})
export class CreatePresentationStep1 {
public constructor(public presentationService: PresentationService) { }
}
The service looks like this:该服务如下所示:
@Injectable()
export class PresentationService {
public fileSelected?: File;
public constructor() {
this.handlers();
}
private handlers(): void {
new BehaviorSubject<File>(this.fileSelected).subscribe({
next: (file) => {
console.log('file', file);
}
});
}
}
When the component loads, the console log runs and prints file undefined
, which is correct.当组件加载时,控制台日志运行并打印
file undefined
,这是正确的。 When I click on the input field and select a file, the behavior never runs again.当我单击输入字段并选择一个文件时,该行为再也不会运行。 Is that intended?
这是故意的吗? I would expect the call to run again since the variable changed.
由于变量更改,我希望调用再次运行。 How can I get my behavior to run every time the variable changes?
每次变量更改时,如何让我的行为运行?
That's not really how a BehaviorSubject
works.这并不是
BehaviorSubject
的真正工作方式。 What you pass in the constructor is just the default initial value.您在构造函数中传递的只是默认初始值。 It cannot monitor a property.
它无法监控资产。 In your case, this code should work:
在您的情况下,此代码应该有效:
<input type="file" [ngModel]="presentationService.fileSelected$ | async"
(ngModelChange)="presentationService.fileSelected$.next($event)">
@Component({
selector: '...',
templateUrl: '...'
})
export class CreatePresentationStep1 {
constructor(public presentationService: PresentationService) { }
}
@Injectable()
export class PresentationService {
public readonly fileSelected$ = new BehaviorSubject<File | void>(void 0);
public constructor(private _httpClient: HttpClient) {
this.handlers();
}
private handlers(): void {
this.fileSelected$.subscribe({
next: (file) => {
console.log('file', file);
}
});
}
}
Although this is not entirely like I would do it.虽然这并不完全像我会做的那样。 This gives consumers of your
PresentationService
full access to the subject/observable, but it's one way :)这使
PresentationService
消费者可以完全访问主题/可观察对象,但这是一种方式:)
Try this:尝试这个:
<input type="file" (change)="fileChangeEvent($event)">
Bind event listener in component:在组件中绑定事件监听器:
@Component({
selector: '...',
templateUrl: '...'
})
export class CreatePresentationStep1 {
public constructor(public presentationService: PresentationService) { }
public fileChangeEvent(fileInput: any) {
const file = fileInput.target.files[0];
this.presentationService.handlers(file).subscribe(file => console.log('file', file));
}
}
And in Service:并在服务中:
@Injectable()
export class PresentationService {
public fileSelected?: File;
private handlersSubject= new BehaviorSubject<File>(undefined);
public handlerObs$ = this.handlersSubject.asObservable();
public handlers(file: any): void {
this.handlersSubject.next(file);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.