角度可观察数组,由 http 请求和手动添加的数据填充



我试图了解 Angular 6 中的可观察量,但我对比 AngularJS 更新的任何内容都不熟悉,并且现在正在认真挣扎。我想我已经浏览了我能找到的所有教程并在这里进行了广泛搜索,所以希望我没有错过任何东西,但很乐意接受友好的指示......

我想做的是这样的:

  1. 向后端 API 发出 GET 请求,返回项目的JSON 数组,并将该数组作为数据列表显示在组件中
  2. 允许第二个组件将新项发布到后端,并将该项添加到上面的列表中

我猜我正在描述一个可观察量,因为 #1 需要异步,但我看到的所有示例似乎只处理两个步骤中的一个,而不是两个步骤。我错过了什么?

@1:向后端 API 发出 GET 请求,返回项目的 JSON 数组,并将该数组作为数据列表显示在组件中

我们称之为组件 A:

export class ComponentA {        
arrayOfItems:Type[];
constructor(private http:HttpClient) {}
getDataFromAPI():Observable<Type[]> {
this.http.get<Type[]>('api-get-url')
.subscribe(
(items) => {
//print them if you want;console.log('response from the api', items);
this.arrayOfItems = items;
}
)
}
}

@2.1:允许第二个组件将新项目发布到后端(故意省略了部分问题(

export class ComponentB {  
// let's assume this array is already populated
// via you 2-way bindings or whatever means 
newItems:Type[];
constructor(private http:HttpClient) {}
postDataToAPI():Observable<any> {
this.http.post('api-post-url', this.newItem)
.subscribe(
response => console.log('response from the api', response);
)
}
}

@2.2并将该项目添加到上面的项目列表中

一切^都很简单,但现在你必须停下来想一想:我有一些"这里"和一些"那里"的东西。我怎么能...连接它们?医 管 局!连接!所以我需要某种机制来连接 2 个组件。你是做什么工作的?您使用服务!但用途是存储共享数据集的服务。您可以将其称为数据存储服务。

让我们(重新(编写一些代码:

@Injectable()
export class DataStoreService() {
items:Type[] = [];
constructor(private http:HttpClient) {}
getDataFromTheAPI():Observable<Type[]> {
this.http.get<Type[]>('api-get-url')
.subscribe(items => this.items = items)
}
postDataToTheAPI(itemToAdd:Type):Observable<any> {
this.http.post('api-post-url', itemsToAdd)
.subscribe(
(response) => {
// check if all is good, and add it to the 'items' array
addItem(itemToAdd);
}
}
)
}
getItems() {
return this.items;
}
addItem(item:Type) {
this.items.push(item);
}
}

现在,您的组件 A 更改为:

export class ComponentA implements OnInit{
constructor(private dataStoreService: DataStoreService) {}
ngOnInit(): void {
this.dataStoreService.getDataFromTheAPI(); 
// ^ will request the data from the API and store it 
// inside the service
}
// and here you get a reference to that data
get itemsReferenceFromService() {
return this.jobsStoreService.getJobsArray();
}
}

组件 B 用于:

export class ComponentB {
newItem:Type;
constructor(private dataStoreService: DataStoreService) {}
// when you do this, if successful, addItem method
// will also be called that will 'and also add that item to the list of items above'; as componentA only has a reference to the data in 
// the service, the new item will be displayed it it
this.dataStoreService.postDataToTheAPI(newItem);
}

希望这能回答你的问题。如果您有任何其他疑问,请大声说出来。省略了网址等信息。

进一步的改进是使用另一个处理 API 调用的服务,并保持数据服务清洁仅用于存储目的。这将简化测试

请注意,角度中任何服务/组件的生命周期都取决于最终用户刷新页面。所描述的服务不是持久性机制。

那是因为它是两回事。

第一个是您期望从中获取数据的请求。 所以你订阅了它。

$newsletter = NewYorkTimesService.getData(); // this does some http stuff.
$newsletter.subscribe(newspaper => readData(newpaper) /*or whatever you want to do with json */ );

第二个是完全不同的调用(和不同的可观察量(来发送数据,你只是真正订阅才能知道它是否成功。

$paymentResults = NewYorkTimesService.makePayment(paymentJSON); //this does http stuff too.
$paymentResults.subscribe(() => /*I guess it was successful */ , (error)=> /*it failed */);

它们唯一共享的是,它们可能与从同一服务调用的相同。

这是在 Angular 5 中执行此操作的基本示例。我认为 5 和 6 之间唯一可能不同的是您要导入的库来自哪里。

@Injectable()
export class ItemsService {
constructor(private http: HttpClient) { }
private backendURL= "http://myurl.endpoint.com/";
getItems(): Observable<IItem[]> {
return this.http.get<IItem[]>(backendURL);
}
saveItems(items: IItem[]): Observable<IItem[]> {
let options = { headers: new HttpHeaders({'Content-Type': 'application/json'})};
return this.http.post(backendUrl, items, options);
}
}

在组件类中,导入组件并订阅它。

export class ItemComponent {
itemList: Item[];
constructor(private itemService: ItemService) { }
ngOnInit() {
this.itemService.getItems().subscribe(data => this.itemList = data);
}  
}

这是一个非常好的教程,介绍了基础知识 https://angular.io/tutorial

最新更新