【问题标题】:BehaviorSubject returning wrong dataBehaviorSubject 返回错误数据
【发布时间】:2020-08-04 15:59:37
【问题描述】:

我尝试在我自己的小应用程序中使用 BehaviorSubject,该应用程序存储所选复选框的状态。这是应用程序的链接Stackblitz Code

我在需要维护其选中状态的页面上有一个国家复选框列表(墨西哥、加拿大、美国等)。为此,我正在使用带有 BehaviorSubject 的 Angular 服务。 每当我选择几个复选框然后单击页面上的保存按钮时,我会将复选框选中的状态数据传递给服务,然后服务通过 BehaviorSubject 将该数据传递回组件。

如果单击应用按钮,组件只会将复选框状态数据传递给服务,但是,当我选中几个复选框,然后使用路由器链接导航到应用程序上的不同页面(例如主页)时,以及何时我回到带有所有复选框的菜单页面,服务中的 BehaviorSubject 返回被单击的复选框。这很奇怪,不是吗?我在这里错过了什么?

注意:只有当用户单击保存按钮时,我才会调用 storeData 方法。即使我在 save 方法中注释了对 storeData 方法的调用,我也会看到相同的行为。它是否与 BehaviorSubject 有关系?我正在使用 BehaviorSubject 以便服务在组件加载和订阅 options$ 时传递以前的数据@

代码如下: component.html

    <div class="countries" *ngFor="let item of data">
      <input
        [id]="item"
        type="checkbox"
        [checked]="selectedOption[item]"
        [value]="item"
        (change)="onToggle($event)"
      />
      <label [for]="item">{{ item }}</label>
    </div>

    <button (click)="saveOptions()">Save</button>

component.ts

    data = [
        "India",
        "Australia",
        "USA",
        "Brazil",
        "Canada",
        "South Africa",
        "UK",
      ];

      selectedOption = {};

      constructor(private dataService: DataService, private router: Router) {}

      ngOnInit(): void {
        this.dataService.options$.subscribe((data) => {
          console.log(data);
          this.selectedOption = data;
        });
      }

      onToggle(event) {
        this.selectedOption[event.target.value] = event.target.checked;
      }

      saveOptions() {
        this.dataService.storeData(this.selectedOption);
        this.router.navigate(["/home"]);
      }

data.service.ts

    selectedOptions = {};
      optionsAction = new BehaviorSubject<any>(this.selectedOptions);
      options$ = this.optionsAction.asObservable();

      constructor() {}

      storeData(data) {
        this.selectedOptions = data;
        this.optionsAction.next(data);
      }

【问题讨论】:

    标签: angular rxjs angular-material angular8 behaviorsubject


    【解决方案1】:

    您订阅了可观察的selectedOptions$,并将值设置为主题_selectedOptionsAction,但它们是不同的:

     ngOnInit(): void {
        this.sub = this._megamenu.selectedOptions$.subscribe(data => {  //this observable never emitted values
          console.log(data);
          this.selectedOptions = data.selectedOptions;
        })
      }
    

    这个订阅不能针对_selectedOptionsAction 主题(我的意思是next() 和subscribe() 只来自一个主题,为什么要添加混淆)?

    【讨论】:

      【解决方案2】:

      我会走这条路:

      service.ts

      selectedOptions: any = {};
      
      private _selectedOptionsAction$ = new BehaviorSubject<any>({
          selectedOptions: this.selectedOptions,
      });
      
      getSeletedOptionsData(): Observable<any> {
          return this._selectedOptionsAction$.asObservable();
      }
      
      storeSeletedOptionsData(data: any): void {
          this.selectedOptions = data.selectedOptions;
          this._selectedOptionsAction$.next(data);
      }
      

      component.ts

      ngOnInit(): void {
          this.sub = this._megamenu.getSeletedOptionsData().subscribe((data:any) => {
            console.log(data);
            this.selectedOptions = data.selectedOptions;
          })
      }
      
      apply(): void {
          this._megamenu.storeSeletedOptionsData({
              selectedOptions: this.selectedOptions
          });
      }
      

      【讨论】:

        猜你喜欢
        • 2019-10-18
        • 1970-01-01
        • 2017-08-22
        • 2017-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-25
        • 1970-01-01
        相关资源
        最近更新 更多