Angular 通过可观察到的物体传递物体阵列

Angular 通过可观察到的物体传递物体阵列,angular,rxjs,observable,Angular,Rxjs,Observable,我有一个简单的原型表单,它由两个组件(搜索和结果)和一个服务(查询)组成 为了在详细介绍之前进行简要总结,我希望在搜索组件上执行一项操作,以更新结果窗格中的数据 在我下面发布的原型中,这是一个简单的字符串。我可以在输入框中键入一个字符串,每次单击submit,就会调用设置值的服务(调用service.setData),结果组件会观察到它相应地更改和更新了标签。我也尝试过对一个对象数组做同样的操作,但不管我怎么做,它都拒绝实时更新。但它将在初始负载下工作。我已将该服务添加到提供商中 这是一个简单的

我有一个简单的原型表单,它由两个组件(搜索和结果)和一个服务(查询)组成

为了在详细介绍之前进行简要总结,我希望在搜索组件上执行一项操作,以更新结果窗格中的数据

在我下面发布的原型中,这是一个简单的字符串。我可以在输入框中键入一个字符串,每次单击submit,就会调用设置值的服务(调用service.setData),结果组件会观察到它相应地更改和更新了标签。我也尝试过对一个对象数组做同样的操作,但不管我怎么做,它都拒绝实时更新。但它将在初始负载下工作。我已将该服务添加到提供商中

这是一个简单的测试,有两个按钮调用稍微不同的方法

Set data to:

<input [(ngModel)]="searchTerm" placeholder="Enter data here"/>

<button (click)="getSearchResults1(searchTerm); searchTerm=''">Submit 1</button>
<button (click)="getSearchResults2(searchTerm); searchTerm=''">Submit 2</button>
query.service.ts

constructor(private http: HttpClient) { }

  private data: BehaviorSubject<string> = new BehaviorSubject(null);

  getData(): Observable<string> {
    return this.data;
  }

  setData(d: string): void {
    this.data.next(d);
  }

  ////////////////////////////////////////////////

  private accountData: Observable<Account[]> = new Observable(null);

  private accountUrl = 'assets/accounts.json';
  private accountUrl2 = 'assets/accounts2.json';
  private accountUrl3 = 'assets/accounts3.json';

  getAccountData(): Observable<Account[]> {
    return this.accountData;
  }

  setAccountData1(): void {
    this.accountData = this.http.get<Account[]>(this.accountUrl)
  }
  setAccountData2(): void {
    this.accountData = this.http.get<Account[]>(this.accountUrl2)
  }
  setAccountData3(): void {
    this.accountData = this.http.get<Account[]>(this.accountUrl3)
  }
构造函数(私有http:HttpClient){
私有数据:BehaviorSubject=新的BehaviorSubject(空);
getData():可观察{
返回此.data;
}
setData(d:string):无效{
本.数据.下一(d);
}
////////////////////////////////////////////////
私人账户数据:可观察=新可观察(空);
private accountUrl='assets/accounts.json';
private accountUrl2='assets/accounts2.json';
private accountUrl3='assets/accounts3.json';
getAccountData():可观察{
返回此.accountData;
}
setAccountData1():void{
this.accountData=this.http.get(this.accountUrl)
}
setAccountData2():void{
this.accountData=this.http.get(this.accountUrl2)
}
setAccountData3():void{
this.accountData=this.http.get(this.accountUrl3)
}
results.component.html-顶部的字符串版本工作正常,尝试使用对象数组执行此操作的两个稍有不同的版本都失败了

The new value is: <br />

<div>{{data|async}}</div>

<br /><hr /><br />

Array is: <br />

<ul class="search-result">
    <li *ngFor="let account of accountData|async" >

        {{account.firstName}}

    </li>
  </ul> 

  <ul class="search-result">
    <li *ngFor="let account2 of accountData2" >

        {{account2.firstName}}

    </li>
  </ul> 
新值为:
{{data}异步}


数组为:
    {{account.firstName}
    {{account2.firstName}
results.component.ts

  constructor(private queryService: QueryService) {}

  getSearchResults1(searchTerm: string):void {    
    this.queryService.setAccountData1();
    this.queryService.setData(searchTerm);
  }

  getSearchResults2(searchTerm: string):void {
    this.queryService.setAccountData2();
    this.queryService.setData(searchTerm);
  }

  ngOnInit() {  
    this.queryService.setAccountData3();
  }
  constructor(private queryService: QueryService) {}

  data: Observable<string>;    
  accountData: Observable<Account[]>;    
  accountData2: Account[];

  ngOnInit() {

    this.data = this.queryService.getData();

    this.accountData = this.queryService.getAccountData();

    this.queryService.getAccountData().subscribe(a => this.accountData2 = a);

  }
构造函数(私有queryService:queryService){
数据:可观察;
会计数据:可观察;
accountData2:帐户[];
恩戈尼尼特(){
this.data=this.queryService.getData();
this.accountData=this.queryService.getAccountData();
this.queryService.getAccountData().subscribe(a=>this.accountData2=a);
}
1) 当页面第一次加载时,搜索组件的Onit加载setAccountData3,它在第三个帐户数据集中显示名字列表

2) 我在搜索组件的输入框中键入一个字符串值,然后单击任一按钮,字符串值将实时输出到结果组件上

3) 对象数组在两个按钮上都不更新。两个submit按钮都使用稍微不同的方法更新数组。我可以通过向控制台输出来判断是否正在设置数组值,但是结果组件没有看到与字符串版本上几乎相同的编码相同的操作

编辑。。。。。。。。。。。。。。。。。
为了确认这一点,我将使用一个简单的原型来测试我在以后的项目中需要的原则。我知道在这个特殊的例子中,我可以简化解决方案以达到我想要的结果。我特别希望一个组件“侦听”服务中的更改并对其进行操作,这对字符串来说非常容易,但我无法让它对对象数组工作。

首先,对于HTML,我不确定为什么要将两个组件搜索和结果分开。你可以把两者结合起来。对于Angular,当您有2个HTML组件(以您的为例)时,您将有2个单独的component.ts、component.spec.ts等,链接它们将有点挑战性。我建议将它们结合在一起。其次,因为您使用的是[(ngModel)],所以不必将属性“searchTerm”传递到方法中。这是我建议的解决办法

.component.html

query.service.ts

constructor(private http: HttpClient) { }

  private data: BehaviorSubject<string> = new BehaviorSubject(null);

  getData(): Observable<string> {
    return this.data;
  }

  setData(d: string): void {
    this.data.next(d);
  }

  ////////////////////////////////////////////////

  private accountData: Observable<Account[]> = new Observable(null);

  private accountUrl = 'assets/accounts.json';
  private accountUrl2 = 'assets/accounts2.json';
  private accountUrl3 = 'assets/accounts3.json';

  getAccountData(): Observable<Account[]> {
    return this.accountData;
  }

  setAccountData1(): void {
    this.accountData = this.http.get<Account[]>(this.accountUrl)
  }
  setAccountData2(): void {
    this.accountData = this.http.get<Account[]>(this.accountUrl2)
  }
  setAccountData3(): void {
    this.accountData = this.http.get<Account[]>(this.accountUrl3)
  }
构造函数(私有http:HttpClient){
private accountUrl='assets/accounts.json';
private accountUrl2='assets/accounts2.json';
private accountUrl3='assets/accounts3.json';
setAccountData1():可观察{
返回this.http.get(this.accountUrl)
}
setAccountData2():可观察{
返回this.http.get(this.accountUrl2)
}
setAccountData3():可观察{
返回this.http.get(this.accountUrl3)
}

如果导入ChangeDetectorRef并强制执行cdr.detectChanges(),会发生什么情况?如果代码使用“string”但不使用数组,则不会看到数组发生变化。请尝试使用cdr对此进行分类,如果它有效,则需要确保阵列更新以不同的级别进行实施,以便进行应答。在这个原型中,我保持了它的简单性,它可以被简化。它主要是关于测试原理的,所以当我以后想把它用于更复杂的项目时,我可以做。我明白了。我看到你的一些作品没有正确使用,所以我做了调整。对你有用吗?[编辑]如果您可能需要,我可以回答有关可观察的问题。是的,当我尝试上述方法时,它确实适用于上述简单示例。在一个即将到来的项目中,我需要一个由多个组件调用和订阅的服务,但我认为您的示例不允许我这样做。
searchTerm: any;
constructor(private queryService: QueryService) {}

ngOnInit() {  
  this.getSearchResults3();
}

  getSearchResults1()  {    
    this.queryService.setAccountData1()
      .subcribe(data => {
         this.searchTerm = data;
      }
  }

  getSearchResults2()  {
    this.queryService.setAccountData2()
      .subcribe(data => {
         this.searchTerm = data;
      }
  }

  getSearchResults3()  {
    this.queryService.setAccountData3()
        .subcribe(data => {
          this.searchTerm = data;
        }
 }
constructor(private http: HttpClient) { }

  private accountUrl = 'assets/accounts.json';
  private accountUrl2 = 'assets/accounts2.json';
  private accountUrl3 = 'assets/accounts3.json';

  setAccountData1(): Observable<Account>{
    return this.http.get<Account>(this.accountUrl)
  }
  setAccountData2(): Observable<Account>{
    return this.http.get<Account>(this.accountUrl2)
  }
  setAccountData3(): Observable<Account>{
    return this.http.get<Account>(this.accountUrl3)
  }