我有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>
答案 0 :(得分:2)
Observable.of
是一次事件:
创建一个Observable,该Observable发出一个您指定为参数的值,一个接一个地发出,然后发出一个完整的通知。
关于完整通知的最后一部分很重要,因为一旦完成(第一次执行),它将发出complete
事件,并且不再发出。您需要做的是使用Subject
或BehaviorSubject
以获得持续的事件流。
尝试这样的事情:
@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
数组中,您无法在header
或menu
组件中提供服务,则必须在它们上方的组件中提供它(例如app.module
或app.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变量,您可以订阅该变量并侦听该变量中的更改。