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