我在让 ngIf 拾取可观察值时遇到了一些问题。我有两个组件,我试图让一个组件导致另一个组件显示或不显示内容。
filterComponent.ts
import { Component, OnInit } from '@angular/core';
import{Observable } from "rxjs";
import {FilterDataService} from "./filter-data.service";
import {FormsModule} from "@angular/forms";
@Component({
selector: 'app-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.css']
})
export class FilterComponent implements OnInit {
show: boolean;
constructor(private filterData: FilterDataService) { }
ngOnInit() {
this.filterData.currentSource.subscribe(show => this.show =show);
this.changeShowFlag(true);
console.log('Filter Show is ' + this.show);
}
changeShowFlag(showFlag:boolean) {
this.filterData.changeSource(showFlag);
console.log("current show value " + showFlag);
console.log("value of show confirmed as "+ this.show);
console.log("value in service for source " + this.filterData.source);
}
}
filterComponent.html
<p>
filter works!
</p>
<div class ="toggles">
<div class="toggle-border">
<input [(ngModel)]="show"
(click)="changeShowFlag(!show);" type="checkbox" id="one" />
<label for="one">
<div class="artHandle"></div>
</label>
</div>
</div>
filterDataService.ts
import { Injectable } from '@angular/core';
import {BehaviorSubject} from "rxjs/BehaviorSubject";
@Injectable()
export class FilterDataService {
private _Source = new BehaviorSubject<boolean>(true);
public source:boolean = true;
currentSource = this._Source.asObservable();
constructor() { }
changeSource(sourceFlag: boolean) {
this._Source.next(sourceFlag);
this.source = sourceFlag;
}
}
consumerComponet.ts
import { Component, OnInit } from '@angular/core';
import { FilterDataService} from "../filter/filter-data.service";
@Component({
selector: 'app-consumer',
templateUrl: './consumer.component.html',
styleUrls: ['./consumer.component.css']
})
export class ConsumerComponent implements OnInit {
source: boolean;
constructor(private filterData: FilterDataService) { }
ngOnInit() {
this.filterData.currentSource.subscribe(source => this.source = source );
}
}
consumerComponent.html
<p>
consumer works!
</p>
<div *ngIf="source" >
show is on
</div>
app.modules.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { FilterComponent } from './filter/filter.component';
import { ConsumerComponent } from './consumer/consumer.component';
import {FilterDataService} from "./filter/filter-data.service";
import {FormsModule} from "@angular/forms";
@NgModule({
declarations: [
AppComponent,
FilterComponent,
ConsumerComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [FilterDataService],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<div>
<app-filter></app-filter>
</div>
<div>
<app-consumer></app-consumer>
</div>
现在,如果我单击 slider ,值就会更改,并会获得控制台输出,正如预期的那样,告诉我值已更改,但由于某种原因,使用 ngif 的消费者组件不会打开和关闭。正如我所期望的那样。我确信我错过了一些东西,这可能是一个非常简单的修复,但我已经寻找了一周的解决方案,并认为我应该发布这个问题。看看是否有人可以建议我哪里出错了。预先感谢您的任何建议和帮助。
最佳答案
我建议使用异步管道:
source$: Observable<boolean>;
constructor(private filterData: FilterDataService) { }
ngOnInit() {
this.source$ = this.filterData.currentSource;
}
<div *ngIf="source$ | async" >
show is on
</div>
原因有几个,其中之一是它更干净并且可以为您处理异步操作。第二个是您的组件实际上存在内存泄漏,因为您没有取消订阅,异步管道会为您清理这些内存。
还建议您删除此内容:
public source:boolean = true;
来自您的服务。这就是状态,它是错误的来源并且是不必要的。该服务的消费者应该始终使用可观察的。如果您养成了这样混契约(Contract)步和异步操作的习惯,您将会遇到麻烦。
关于angular - NgIf 不使用 observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47444789/