【问题标题】:Angular 8 - Behavior Subject not emitting next value in ServiceAngular 8 - 行为主题未在服务中发出下一个值
【发布时间】:2020-04-28 14:05:30
【问题描述】:

您好,我有一个 Angular 应用程序,我在其中将数据从一个组件传递到服务,并尝试通过调用它的下一个函数来更新该服务中行为主体的值,以便它反过来更新另一个组件中的订阅值.我的问题是当传递数据并创建一个对象以传递给行为主体时,下一个函数不会执行。这是代码。

我的 ShopService.ts

为了篇幅,我在代码中省略了其他函数,但它们应该与我尝试实现的代码无关

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { AuthService } from 'src/app/auth/auth.service';
import { Product } from '../models/product.model';

import { BehaviorSubject } from 'rxjs';
import { take, exhaustMap, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ShopService {

  productsSubject = new BehaviorSubject<Product[]>(null);

  productSubject = new BehaviorSubject<Product>(null);

  productObs = this.productSubject.asObservable();

  private products: Product[];

  private product: Product;

  private userToken;

  constructor(private http: HttpClient, private authService: AuthService) {

  }

 // trying to update the behavior subject here but next never executes but data is logged to console
 editProductForm(id: string, title: string, price: number, imagePath: string, description: string) {
     this.product = new Product(title, price, imagePath, description, id);
     console.log('edit product ' + this.product.title);
     this.productSubject.next(this.product);
  }
}

admin-shop.component.ts

这是我尝试订阅更新后的行为主题值的地方

import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { NgForm } from '@angular/forms';

import { ShopService } from '../services/shop.service';

import { Subscription } from 'rxjs';

import { Product } from '../models/product.model';

@Component({
  selector: 'app-admin-shop',
  templateUrl: './admin-shop.component.html',
  styleUrls: ['./admin-shop.component.css']
})
export class AdminShopComponent implements OnInit {

  @Output() editProductEvent = new EventEmitter<boolean>();

  productSub: Subscription;

  product: Product;

  error: string;

  isLoading = false;

  isEditing = false;

  constructor(private shopService: ShopService) { }

  ngOnInit() {
    this.productSub = this.shopService.productSubject.subscribe(product => {
      if (product) {
        console.log('editing product' + product);
        this.editProductEvent.emit(true);
        this.product = new Product(
          product.title,
          product.price,
          product.imagePath,
          product.description,
          product._id);
      }
    });
  }
}

item-list.component.ts

这是我将数据发送到服务的地方,我知道它正在发送,因为一旦它到达服务,它就会被记录在控制台中。

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Product } from '../models/product.model';
import { ShopService } from '../services/shop.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-item-list',
  templateUrl: './item-list.component.html',
  styleUrls: ['./item-list.component.css']
})
export class ItemListComponent implements OnInit, OnDestroy {

  products: Product[] = [];

  private shopSub: Subscription;

  private subjectSub: Subscription;

  constructor(private shopService: ShopService) { }

  editProduct(id: string, title: string, price: number, imagePath: string, description: string) {
    this.shopService.editProductForm(id, title, price, imagePath, description);
  }
}

我提供的代码是问题所在,因为我已经在我的应用程序的其他部分中按预期工作的行为主题只是当我将数据从项目列表组件发送到它记录的服务时数据,但不会更新行为主题,并且它永远不会到达订阅,因为没有数据记录在管理商店组件订阅代码中。

希望我已经提供了足够的信息来找到答案,但如果没有,请询​​问您认为必要的更多信息。在此先感谢:)

这里是 app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { HomeComponent } from './home/home.component';
import { AuthComponent } from './auth/auth.component';
import { DropDownDirective } from './util/dropdown.directive';
import { HttpClientModule } from '@angular/common/http';
import { LoadingSpinner } from './util/loading-spinner/loading-spinner.component';
import { AdminComponent } from './admin/admin.component';
import { DashboardComponent } from './admin/dashboard/dashboard.component';
import { AdminShopComponent } from './admin/dashboard/admin-shop/admin-shop.component';
import { AdminProfileComponent } from './admin/dashboard/admin-profile/admin-profile.component';
import { ItemListComponent } from './admin/dashboard/item-list/item-list.component';
import { BlockchainComponent } from './blockchain/blockchain.component';


@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    HomeComponent,
    AuthComponent,
    DropDownDirective,
    LoadingSpinner,
    AdminComponent,
    DashboardComponent,
    AdminShopComponent,
    AdminProfileComponent,
    ItemListComponent,
    BlockchainComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

【问题讨论】:

  • 您可能有两个不同的服务实例。向 t 添加一个构造函数,其中包含一个 colnsole.log() 语句。检查您获得该声明的次数。
  • 你在任何模块的提供者部分提供你的服务吗?
  • 我同意@JB Nizet,你能发布你的app.module
  • 并非所有服务都定义为@Injectable({ providedIn: root })。是的,我稍后会发布我的 app.module.ts。谢谢大家
  • 在那里发布了 app.module.ts

标签: angular typescript rxjs angular-services


【解决方案1】:

我的服务导入文件在两个组件中都不同 - 在一个组件中我使用 services/SeekerJobService.js 和其他服务/SeekerJobService

这就是为什么订阅的对象为空。

【讨论】:

    【解决方案2】:

    您在将事件发射器设置为 true 的同一组件内实例化事件发射器。所以它让自己知道它已被编辑但没有其他人。由于您使用的是服务,因此您可以在变量发生更改时更新该变量并订阅组件中的该更改。祝你好运!

    【讨论】:

      【解决方案3】:

      您的服务似乎没有被实例化。尝试将您的服务导入到Providers下的app.module

      Import { ShopService } from '../services/shop.service';// Or wherever it's at
      ...
        providers: [ShopService],
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-12
        • 1970-01-01
        • 1970-01-01
        • 2020-10-27
        • 2021-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多