angular - 通过 Observable 传递对象数组
问题描述
我有一个简单的原型表单,它由两个组件(搜索和结果)和一个服务(查询)组成。
在详细介绍之前简要总结一下,我希望在搜索组件上执行一个操作来更新结果窗格中的数据。
在我下面发布的原型中,这适用于一个简单的字符串。我可以在输入框中输入一个字符串,每次单击提交时都会调用设置值的服务(调用 service.setData),结果组件会观察到它相应地更改并更新了标签。我试过对一个对象数组做同样的事情,但无论我尝试什么,它都拒绝实时更新。它会在初始负载上工作。我已将服务添加到提供程序中。
search.component.html - 因为这是一个简单的测试,它有两个按钮调用略有不同的方法。
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>
search.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();
}
查询.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)
}
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>
结果.component.ts
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);
}
1) 页面首次加载时,搜索组件的 Onit 会加载 setAccountData3,它会显示第三个帐户数据集中的名字列表。
2)我在搜索组件的输入框中输入一个字符串值,点击任意一个按钮,字符串值会实时输出到结果组件上。
3) 对象数组不会在任一按钮上更新。两个提交按钮都使用稍微不同的更新数组的方法。我可以从输出到控制台得知正在设置数组值,但结果组件看不到这个动作,就像它在字符串版本上使用几乎相同的编码一样。
编辑........ 确认这是一个简单的原型,用于测试我在以后的项目中需要的原则。我知道在这种特殊情况下,我可以简化解决方案以达到我想要的结果。我特别想要一个组件来“监听”服务中的变化并对其采取行动,这很容易适用于字符串,但我无法让它适用于对象数组。
解决方案
首先,对于 HTML,我不确定您为什么要划分 2 个组件搜索和结果。您可以将两者结合起来。对于 Angular,当您有 2 个 HTML 组件(以您的为例)时,您将有 2 个单独的 component.ts、component.spec.ts 等,并且将它们链接起来会有点挑战。我建议将它们组合在一起。其次,因为您使用的是 [(ngModel)],所以您不必将属性“searchTerm”传递给方法。这是我建议的解决方案
.component.html
<input [(ngModel)]="searchTerm" placeholder="Enter data here"/>
<button (click)="getSearchResults1()>Submit 1</button>
<button (click)="getSearchResults2()>Submit 2</button>
<-- YOUR RESULT WILL SHOWED HERE -->
The new value is: <br />
<div>{{data|async}}</div>
<br /><hr /><br />
Array is: <br />
<ul class="search-result">
<li *ngFor="let account of searchTerm | async" >
{{account.firstName}}
</li>
</ul>
<ul class="search-result">
<li *ngFor="let account2 of searchTerm " >
{{account2.firstName}}
</li>
</ul>
从此,您的 component.ts 将是这样的
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;
}
}
查询.service.ts
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)
}
推荐阅读
- r - R - 根据最近的匹配列查找和更新
- java - 如何在 listview 中更改 cardview 的标题字符串?安卓工作室 Java
- javascript - jqgrid json数据数组插入
- javascript - 图像未在 webpack 中加载 + 在图像输出文件夹之外还有另一个图像
- android - 在 ASP.NET Core WebAPI 后端沿 React/Android 应用程序前端集成 Google + Facebook 身份验证
- python - Finplot 依赖问题。Pyqt 5.15.6 不兼容
- c++ - auto &i 范围的正确用途?
- git - Cloud Source Repositories - Git 将代码推送到默认分支或切换分支
- java - Java 列表 - IndexOutOfBounds 异常错误
- google-sheets - 与多个标准(和范围数字)的索引匹配