【问题标题】:How to get the latest data from Angular Service?如何从 Angular Service 获取最新数据?
【发布时间】:2022-06-11 12:07:02
【问题描述】:

如果我试图从服务中获取数据,该数据是从另一个组件更新的,我该怎么做?

下面是一个描述我的问题的例子,虽然它是一个不好的例子。

如果我有一个名为 userInfoService 的服务,它只存储用户名。

@Injectable({providedIn: 'root'})
export class UserInfoService {
  userNames?: string[];
}

还有一个组件:SignUpPageComponent 更新用户名

@Component...
export class SignUpStepComponent {
  constructor(private userInfoService: UserInfoService){}
  
  // do something and...
  this.userInfoService.userNames = [Tim];
}

如何在另一个组件中获取用户名:ReviewAccountStepComponent?或者具体来说,ReviewAccountStepComponent 应该什么时候调用该函数来获取最新的名字?

SignUpStepComponent 和 ReviewAccountStepComponent 都处于同一级别,如果这很重要的话。

@Component...
export class ReviewAccountStepComponent {
  customerNames: string[];
  constructor(private userInfoService: UserInfoService){}
  
  ngOnInit() { // won't work
    this.customerNames = this.userInfoService.userNames;
  }
}

【问题讨论】:

  • 使用服务很棒。但是,您可以将其推送到 Subject 并从其他组件订阅此 Subject,而不是将值存储在变量中

标签: angular angular-services


【解决方案1】:

不,它不是那样工作的,您需要将数据存储在服务中的可观察对象(主题)中。

现在第二个组件应该订阅 ngOnInt 中的这个 observable。

我从您的场景中了解到的问题是您将列表存储在服务中。当第二个组件加载时,它只会在 ngOnInt 上读取此数据一次。 现在,只要这个列表被第一个组件修改,它就会在服务中更新。第二个组件永远不会收到更改通知,因为它只在创建此组件时读取列表一次

使用 observable,您可以动态观察这些数据的变化,

另外让我添加一个示例以使其更清楚。 Github

这是第二个组件将要观察的主题的服务

文件名:data.service.ts

    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class DataService {
    
      data:Subject<string> = new Subject<string>();
    
    
      constructor() { }
    
      submit(val:string){
      
        this.data.next(val);
      }
    }

这是第一个组件:

component1.component.css

    .comp1{
        border: 1px solid black;
        padding: 20px;
        margin: 20px;
    }

component1.component.html

    <div class="comp1">
        <input [(ngModel)]= "dataField" />
        <button (click)="onsubmit()">submit</button>
    </div>

component1.component.ts

    import { Component, OnInit } from '@angular/core';
    import { DataService } from '../data.service';
    
    @Component({
      selector: 'app-component1',
      templateUrl: './component1.component.html',
      styleUrls: ['./component1.component.css']
    })
    export class Component1Component implements OnInit {
    
      dataField:string='';
      constructor(private dataService:DataService) { }
    
      ngOnInit(): void {
      }
    
    
      onsubmit(){
    
        this.dataService.submit(this.dataField);
      }
    }

这是第二个组件

comp2.component.css

    .comp2{
        border: 1px solid black;
        padding: 20px;
        margin: 20px; }
    
    .received{
        color:red }

comp2.component.html

    <div class="comp2">
        <div>
            <label>
                showing data from first component via service
            </label>
        </div>
        
    
        <div class="received">
            <label>
                {{receivedvalue}}
            </label>
        </div>
       
    </div>

comp2.component.ts

    import { Component, OnInit } from '@angular/core';
    import { Observable } from 'rxjs';
    import { DataService } from '../data.service';
    
    @Component({
      selector: 'app-comp2',
      templateUrl: './comp2.component.html',
      styleUrls: ['./comp2.component.css']
    })
    export class Comp2Component implements OnInit {
    
      receivedvalue:any;
    
      constructor(private dataService: DataService) { }
    
      ngOnInit(): void {
    
        this.dataService.data.subscribe(data=>{
          this.receivedvalue=data;
        });
      }
    
    }

app-component.html

    <app-component1></app-component1>
    <app-comp2></app-comp2>

不要忘记在 app.module.ts 中导入 FormsModule,因为我们在输入字段的第一个组件中使用了双向绑定

输出看起来像是通过使用主题的服务发生的这种通信 b/w 组件

【讨论】:

  • 是的!这就是我需要的!在深入研究了一些真实案例后,我发现 subscribe/observable 可能是我的问题的解决方案。
  • @timDemo 太好了,如果您认为这回答了您的问题,那么接受答案并投票可能会很棒。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多