【问题标题】:Behavior subject not updating subscriber on .next(value)行为主体未在 .next(value) 上更新订阅者
【发布时间】:2019-06-03 06:57:11
【问题描述】:

我在获取 Behavior Subject 以更新 .next(value) 调用中的订阅者时遇到问题。

我是打字稿的新手,但我想我一定是遗漏了一些小东西。从我所看到的来看,这似乎是正确的。

网站上有很多这样的问题,但没有一个能解决我的问题。这是一个例子。 Subscriber doesn't receive value from .next()

RestService 只放在 app.module.ts providers 数组中。

身份验证保护文件 (services/auth-guard.service.ts)


authenticated = false;

...

    ngOnInit(){
        this.restService.isLoggedIn().subscribe({
            next: result => {
                this.authenticated = result;
            }
        });
    }

...

    canActivate(route: ActivatedRouteSnapshot): boolean{

        console.log(this.authenticated);

        if(!this.authenticated){
            this.router.navigate(['login']);
        }
        return this.authenticated;
    }
}

部分休息服务文件(services/rest.service.ts)

import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { RequestOptions } from '@angular/http';
import { Injectable } from '@angular/core';
import { Storage } from  '@ionic/storage';
import { Observable, BehaviorSubject } from  'rxjs';
import { User } from  'src/app/Interfaces/user';
import { tap } from 'rxjs/operators';

...

authSubject  =  new  BehaviorSubject(false);

...

public _setAuthSubject(value){
    this.authSubject.next(value);
 }

public isLoggedIn() {
    return this.authSubject.asObservable();
  }

在 canActivate 中,我有一个控制台日志显示 this.authenticated 始终为假,但如果我在此下添加另一个订阅者调用并打印另一个变量,我可以看到它现在实际上是真的并且它已正确更新。我是否遗漏了一些导致身份验证无法更新的内容?

一些附加信息。这是我的 app.module.ts

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    HttpClientModule,
    IonicStorageModule.forRoot()
  ],
  providers: [
    AuthGuardService,
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    SQLite,
    SQLitePorter,
    RestService,
  ],
  bootstrap: [AppComponent]
})

还有调用auth guard服务的路由(app-routing.module.ts)

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { AuthGuardService } from './services/auth-guard.service';

const routes: Routes = [
  { path: '', loadChildren: './tabs/tabs.module#TabsPageModule', canActivate: [AuthGuardService]},
  { path: 'login', loadChildren: './login/login.module#LoginPageModule' },
];
@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

最后这里是调用的函数,它实际上将身份验证主题设置为 true (login/login.page.ts)

constructor(
    public menu: MenuController,
    private restService: RestService,
    private router: Router,
    private storage: Storage
  ) { }


  async login(form){

    this.restService.login(form.value).subscribe({
      next: response => {
        console.log(response)
        if(response.access_token){
          this.storage.set("ACCESS_TOKEN", response.access_token);
          this.restService._setToken(response.access_token);
          this.restService._setAuthSubject(true);
        }
        this.router.navigateByUrl('');
      },
      error: err => {
        console.log('ERROR!: ', err)
      }
    });
  }

【问题讨论】:

  • 在您的服务中,您正在更新 authSubject,而在您的组件中,您正在订阅 isLoggedIn()。 isLoggedIn() 是做什么的?它与 authSubject 有什么关系?也许您可以在帖子中解释或添加一些代码
  • @lhraf 哦,对不起,这显然会有所帮助。我在其中添加了这一点。IsLoggedIn 将 authsubject 作为可观察对象返回。
  • 我看起来不错。我认为问题不在于行为主体。这可能是您的 DI 设置。您可以检查您的休息服务是否没有被重新启动,使您的守卫始终具有相同的初始值(false)。
  • 我也很好奇这个。所以在我的console.log(this.authenticated)下我添加了另一个订阅(每次调用此函数时都会订阅),该值显示为true。或者你的意思是auth gaurd服务(第一个代码sn-p)。
  • @ingkevin 我也不确定你所说的 DI 设置是什么意思。

标签: typescript ionic4 subscribe behaviorsubject auth-guard


【解决方案1】:

使用以下代码修改了 AuthGuard。服务不能在 ngOnInit 中有代码,我不知道! Nooby 错误...感谢 @ingkevin 和 @lchraf 的所有帮助。

    init(){
        this.restService.isLoggedIn().subscribe({
            next: result => {
                this.authenticated = result;
            }
        });
    }

    constructor(private router: Router, 
                public restService: RestService) {
                    this.init()
                }

ngOnInit 已被移除。

【讨论】:

    【解决方案2】:

    我在 BehaviourSubject 上创建了一个演示,请看看可能有助于解决您的问题。

    https://stackblitz.com/edit/behavioursubject-angular-demo

    【讨论】:

      猜你喜欢
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      相关资源
      最近更新 更多