Angular Observable不会实时向我显示值

时间:2018-10-23 14:52:43

标签: angular angular6

我有2个组件(菜单和标题)和一个服务。我要做的是,当他们从菜单中选择一个项目时,菜单将文本发送到服务,服务将其发送到标题并进行更改。我已经设法将其发送到服务,但是我不知道为什么在带有Observable的标头中它不更新。

服务:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import 'rxjs/add/observable/from'; 
import { of } from 'rxjs';

@Injectable()
export class passVarHelper{

    currentIndex: string;
    constructor(

    ){
        this.currentIndex = "Title";
    }


    getIndex(): Observable <string> {
        return of(this.currentIndex);
    }

    changeIndex(index:string){
        this.currentIndex = index;
        console.log(this.currentIndex);
    }



}

标题:

import { Component, OnInit } from '@angular/core';
import { passVarHelper } from 'src/app/helpers/passVar.helper';

@Component({
  selector: 'app-headerpage',
  templateUrl: './headerpage.component.html',
  styleUrls: ['./headerpage.component.css'],
  providers: [passVarHelper]
})
export class HeaderpageComponent implements OnInit {
  index:string;
  constructor(private _passVarHelper: passVarHelper) {

   }

  ngOnInit() {
    this.loadIndex();
  }

  loadIndex(){
    this._passVarHelper.getIndex().subscribe(
      response  => {
        if(response){
          console.log(response);
          this.index = response;
        }
      },
      error => {
        console.log(<any>error);
      }
    );
  }

}

菜单:

import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { passVarHelper } from 'src/app/helpers/passVar.helper';

@Component({
  selector: 'app-asidenavbar',
  templateUrl: './asidenavbar.component.html',
  styleUrls: ['./asidenavbar.component.css'],
  providers: [passVarHelper]
})
export class AsidenavbarComponent implements OnInit {


constructor(private _passVarHelper: passVarHelper) { 
  }

  ngOnInit() {

  }


  menuClick(){
    var indexMenu = document.getElementById('menu').innerHTML;
    this._passVarHelper.changeIndex(indexMenu);

  }


}

标题HTML

<div class="content-header">
  <div class="container-fluid">
    <div class="row mb-2">
      <div class="col-sm-6">
        <h1 class="m-0 text-dark">{{index}}</h1>
      </div>
      <div class="col-sm-6">
        <ol class="breadcrumb float-sm-right">
          <li class="breadcrumb-item"><a href="#">Volver</a></li>
        </ol>
      </div>
    </div>
  </div>
</div>

3 个答案:

答案 0 :(得分:2)

根据文档,

Observable.of是一次事件:

  

创建一个Observable,该Observable发出一个您指定为参数的值,一个接一个地发出,然后发出一个完整的通知。

关于完整通知的最后一部分很重要,因为一旦完成(第一次执行),它将发出complete事件,并且不再发出。您需要做的是使用SubjectBehaviorSubject以获得持续的事件流。

尝试这样的事情:

@Injectable()
  export class PassVarHelper {
  currentIndex: string;
  currentIndexObs: BehaviorSubject<string>;

  constructor() {
    this.currentIndex = "Title";
    this.currentIndexObs = new BehaviorSubject<string>(this.currentIndex);
  }

  changeIndex(index: string) {
    this.currentIndex = index;
    this.currentIndexObs.next(this.currentIndex);
  }
}

然后使用loadIndex方法:

loadIndex() {
  this._passVarHelper.currentIndexObs.subscribe(
    response => {
      if (response) {
        console.log(response);
        this.index = response;
      }
    },
    error => {
      console.log(<any>error);
    }
  );
}

下面是stackblitz个示例,演示了此行为。

编辑:好的,我知道问题出在哪里……在providers数组中,您无法在headermenu组件中提供服务,则必须在它们上方的组件中提供它(例如app.moduleapp.component)。如果同时在这两个组件中提供服务,则您将获得该服务的不同实例,而您想要实现的目标将无法正常工作。

因此,在其中一个(如果另一个是第一个的子项)或passVarHelper providers 数组中提供app.module.ts(请检查 stackblitz < / em>我提供的示例,我在app.module.ts中提供了服务,并且只在那个地方 提供了服务(为了获得相同的实例)。

嗯,Angular有一个叫做 provider scope 的东西。例如,看一下这个定义:

  

当您在根级别提供服务时,Angular会创建一个共享的服务实例,并插入到任何需要该服务的类中。

这意味着当您在根级别提供服务时,无论使用DI注入到哪里,都将获得该服务的单个实例(就像在构造函数中注入它一样)。

但是,您还可以在任何其他组件中提供服务。通过在组件中提供服务,实际上是将服务仅限制于该组件和该组件内部的组件。本质上,通过在组件中提供服务,当您将该服务注入该组件时,您将获得该服务的新实例(除非它自己提供服务,否则所有子项都将具有该实例)。

因此,该服务及其所有子级都使用服务的单个实例,但是如果在任何子级组件中提供该服务,则该子级及其所有子级都将获得新实例。

希望这使它更加清晰。

有趣的阅读材料:

答案 1 :(得分:1)

在服务中将您的可观察对象创建为类级别变量,并使用std::vector<T>

为其分配值

类似这样的东西(我没有测试代码,只是在概念上对其进行了编辑):

.next()

在标题组件中

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import 'rxjs/add/observable/from'; 
import { of } from 'rxjs';
import {  BehaviorSubject } from 'rxjs';

@Injectable()
export class passVarHelper{

    currentIndex:BehaviorSubject<string>; 
    constructor(){
        this.currentIndex =  new BehaviorSubject<string>('Title');    
     }

    getIndex(): BehaviorSubject<string> {
        return this.currentIndex;
    }

    changeIndex(index:string){
        this.currentIndex.next(index);

    }

}

在标头模板(html)中,使用异步管道绑定索引

index = getIndex();

答案 2 :(得分:0)

嘿,我认为您应该在Angular文档中查看此部分以进行组件交互:https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

您更新了currentIndex变量,但我认为这不会触发Observable正确更新。 currentIndex应该是一个Observable变量,您可以订阅该变量并侦听该变量中的更改。