我想创建一个通用的列表组件,其中包含一些我希望所有列表都具有的功能。理想情况下,我想使用不同的服务作为组件的输入以呈现不同的数据集。角度2有可能吗?
从Angular 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) {
}
}
Run Code Online (Sandbox Code Playgroud)
如果可能的话,如果服务具有一些getItems()返回了Promise的函数,我将如何使用服务中的数据填充items数组。
我也有同样的需求,最终我成功地实现了,到目前为止,效果似乎不错。该实现是用Angular 8编写的。
@Input将传递给子组件的所有服务都应该有一个名为 的方法getItems(),因此,首先,我创建了一个抽象类,它只包含该方法的定义。这个类实际上只不过是一个通知 Angular 有关getItems()方法的容器:
@Injectable()
export abstract class ItemsService {
constructor() { }
/**
* Returns a list of all items
*/
abstract getItems(): Observable<Item[]>;
}
Run Code Online (Sandbox Code Playgroud)
然后,我们可以创建我们的服务 ( 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[]>
}
}
Run Code Online (Sandbox Code Playgroud)
ItemsBService...和 的代码相同ItemsCService。
有关为 Angular 服务创建接口的更多信息,请参见此处。
我们的通用列表组件将包含在父组件中。在此父组件中,我们将注入上述服务,如下所示:
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
) { }
}
Run Code Online (Sandbox Code Playgroud)
然后,在模板中,我们有:
<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>
Run Code Online (Sandbox Code Playgroud)
该组件将有一个@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();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,父组件和子(通用列表)组件将共享相同的服务实例。
https://stackblitz.com/edit/angular-mgubup
我很期待知道是否有另一种更优选的方法来实现这一点。
| 归档时间: |
|
| 查看次数: |
2228 次 |
| 最近记录: |