我想创建一个通用列表组件,其中包含我希望我的所有列表都具有的几个功能。理想情况下,我想使用不同的服务作为组件的输入来呈现不同的数据集。角度2有可能吗?
修改角度2文档中的示例
@Component({
selector: 'Generic List',
template:
`
<h2>Items</h2>
<ul class="items">
<li *ngFor="let item of items"
[class.selected]="isSelected(item)"
(click)="onSelect(item)">
<span class="badge">{{item.id}}</span> {{item.name}}
</li>
</ul>
`
})
export class GTComponent {
@Input() someService: Service;
items: Item[];
private selectedId: number;
isSelected(item: Item) { return item.id === this.selectedId; }
onSelect(item: Item) {
}
}
如果可以,如果服务具有一个返回promise的名为getItems()
的函数,我将如何使用服务中的数据填充items数组。
答案 0 :(得分:2)
我也有同样的需求,最后我设法实现了该实现,到目前为止看来效果很好。 该实现是用 Angular 8 编写的。
所有将作为@Input
传递到子组件的服务都应有一个名为getItems()
的方法,因此,首先,我创建了一个抽象类,该抽象类仅包含以下内容的定义:方法。此类实际上只是一个向Angular通知getItems()
方法的容器:
@Injectable()
export abstract class ItemsService {
constructor() { }
/**
* Returns a list of all items
*/
abstract getItems(): Observable<Item[]>;
}
然后,我们可以创建将实现ItemsAService
的服务(ItemsBService
,ItemsCService
,ItemsService
),如下所示:
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { ItemsService } from './items.service';
import { Item } from './item';
const ITEMS_A: Item[] = [
// our items collection
];
@Injectable()
export class ItemsAService implements ItemsService {
constructor() { }
getItems(): Observable<Item[]> {
return of(ITEMS_A);
// of(ITEMS_A) returns an Observable<Item[]> that emits the array of mock items.
// in real life, you'll call HttpClient.get<Item[]>() which also returns an Observable<Item[]>:
// return this.httpClient.get<Item[]>
}
}
... ItemsBService
和ItemsCService
的相同代码。
有关为Angular Services here创建界面的更多信息。
我们的通用列表组件将包含在父组件中。在此父组件中,我们将注入上述服务,如下所示:
import { Component } from '@angular/core';
import { ItemsAService } from './items-a.service';
import { ItemsBService } from './items-b.service';
import { ItemsCService } from './items-c.service';
@Component({
...
})
export class AppComponent {
constructor(
public itemsAService: ItemsAService,
public itemsBService: ItemsBService,
public itemsCService: ItemsCService
) { }
}
然后,在模板中,我们有:
<app-generic-list
name="A"
[service]="itemsAService"
>
</app-generic-list>
<app-generic-list
name="B"
[service]="itemsBService"
>
</app-generic-list>
<app-generic-list
name="C"
[service]="itemsCService"
>
</app-generic-list>
我们将在此组件中拥有一个@Input() service
,键入ItemsService
,然后从服务中的getItems()
钩子中调用ngOnInit()
方法:
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { ItemsService } from '../items.service';
import { Item } from '../item';
@Component({
selector: 'app-generic-list',
...
})
export class GenericListComponent implements OnInit, OnDestroy {
@Input() name: string;
@Input() service: ItemsService;
items: Item[];
subscription: Subscription;
constructor() { }
ngOnInit() {
if (!this.service) return;
this.subscription = this.service.getItems()
.subscribe(items => this.items = items);
}
// other methods here
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
请注意,父组件和子组件(通用列表)将共享服务的同一实例。
https://stackblitz.com/edit/angular-mgubup
我很想知道是否还有另一种更可取的方法来实现这一目标。