Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在不刷新页面的情况下使用可观察对象的CRUD_Javascript_Angular_Typescript_Rxjs - Fatal编程技术网

Javascript 在不刷新页面的情况下使用可观察对象的CRUD

Javascript 在不刷新页面的情况下使用可观察对象的CRUD,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我试图在angular中使用observables实现CRUD,而不在ts文件中订阅它们,而是在html中使用async 我的目标是获取、添加、编辑和删除从服务器获取的项目,而无需在每次请求后刷新页面 我试着用行为主题,重放主题,异步主题来做这件事,还寻找了一些资料,但我没有发现任何有用的东西 有人能举个例子说明如何用最好的模式实现这种crud吗 在下面,我粘贴了我以前尝试过的代码和API返回的数据结构 提前谢谢 在documents.service.ts中 import { HttpClien

我试图在angular中使用observables实现CRUD,而不在
ts
文件中订阅它们,而是在
html
中使用
async

我的目标是获取、添加、编辑和删除从服务器获取的项目,而无需在每次请求后刷新页面

我试着用
行为主题
重放主题
异步主题
来做这件事,还寻找了一些资料,但我没有发现任何有用的东西

有人能举个例子说明如何用最好的模式实现这种crud吗

在下面,我粘贴了我以前尝试过的代码和API返回的数据结构

提前谢谢

documents.service.ts中

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class DocumentsService {

  constructor(private http: HttpClient) { }

  getDocuments(): Observable<any[]> {
    return this.http.get<any[]>(`https://localhost:5001/docs`)
  }

  postDocument(item: any): Observable<any> {
    return this.http.post<any[]>(`https://localhost:5001/docs`, item)
  }

  putDocument(id: number, item: any): Observable<any> {
    return this.http.put<any[]>(`https://localhost:5001/docs/${id}`, item)
  }

  deleteDocument(id: number): Observable<any> {
    return this.http.delete<any>(`https://localhost:5001/docs/${id}`)
  }
}
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { DocumentsService } from 'src/app/services/documents.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent {

  documents$: Observable<any> = new Observable()

  constructor(private documentsService: DocumentsService) { }
  
  ngOnInit() {
    this.getDocuments();
  }

  getDocuments(): void {
    this.documents$ = this.documentsService.getDocuments()
  }

  postDocument(): void {
    this.documentsService.postDocument({
      "title": "title",
      "description": "lorem ipsum",
      "imageUrl": "https://images.pexels.com/photos/2765111/pexels-photo-2765111.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
      "madeBy": {
        "userName": "mike mock",
        "email": "mike@mock.com"
      }
    })
  }

  putDocument(): void {
    this.documentsService.putDocument(4, {
      "title": "title",
      "description": "lorem ipsum",
      "imageUrl": "https://images.pexels.com/photos/2765111/pexels-photo-2765111.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
      "madeBy": {
        "userName": "mike mock",
        "email": "mike@mock.com"
      }
    })
  }

  deleteDocument(): void {
    this.documentsService.deleteDocument(5)
  }
}
documents.component.html中

家庭作业

加我 编辑我 删除我 {{document | json}}

HTTP获取响应:

[
{
“id”:47,
“标题”:“码头工人”,
“描述”:“lorem ipsum”,
“imageUrl”:https://images.pexels.com/photos/3464632/pexels-photo-3464632.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
“马德比”:{
“用户名”:“迈克·莫克”,
“电子邮件”:mike@mock.com"
}
},
{
“id”:49,
“标题”:“linux”,
“描述”:“第二描述”,
“imageUrl”:https://images.pexels.com/photos/3900437/pexels-photo-3900437.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
“马德比”:{
“用户名”:“迈克·莫克”,
“电子邮件”:mike@mock.com"
}
}
]
HTTP POST/PUT/DELETE响应:

{
“id”:50,
“标题”:“一些文字”,
“描述”:“lorem ipsum”,
“imageUrl”:https://images.pexels.com/photos/2765111/pexels-photo-2765111.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
“马德比”:{
“用户名”:“迈克·莫克”,
“电子邮件”:mike@mock.com"
}
}

可观察对象是惰性的,在订阅之前不会执行

将组件更新为:

从'@angular/core'导入{Component,OnInit};
从'@angular/Router'导入{Router};
从“rxjs”导入{observeable,BehaviorSubject};
从'src/app/services/documents.service'导入{DocumentsService};
@组成部分({
选择器:“应用程序主页”,
templateUrl:“./home.component.html”,
样式URL:['./home.component.scss']
})
导出类HomeComponent{
documents$:BehaviorSubject=新的BehaviorSubject(未定义);
构造函数(私有文档服务:文档服务){}
恩戈尼尼特(){
此文件为.getDocuments();
}
getDocuments():void{
this.documentsService.getDocuments().subscribe(this.documents$);
}
postDocument():void{
this.documents服务.postDocument({
“头衔”:“头衔”,
“描述”:“lorem ipsum”,
“imageUrl”:https://images.pexels.com/photos/2765111/pexels-photo-2765111.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
“马德比”:{
“用户名”:“迈克·莫克”,
“电子邮件”:mike@mock.com"
}
}).subscribe(=>this.getDocuments());
}
putDocument():void{
本文件服务文件(4{
“头衔”:“头衔”,
“描述”:“lorem ipsum”,
“imageUrl”:https://images.pexels.com/photos/2765111/pexels-photo-2765111.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
“马德比”:{
“用户名”:“迈克·莫克”,
“电子邮件”:mike@mock.com"
}
}).subscribe(=>this.getDocuments());
}
deleteDocument():void{
this.documentsService.deleteDocument(5).subscribe(=>this.getDocuments());
}
}

我还强烈建议您键入api并删除
any

的使用问题出在您的服务中。在您的服务中,getDocuments()只是对后端进行调用。在组件中编写此.documents$=this.documentsService.getDocuments()时,它将调用函数一次,读取数据,以后再也不会更新它

因此,您需要创建一个主题来存储服务中的数据,使用.asObservable()使其在外部可用,将组件链接到该可观察对象,并在每次http调用后更新主题的内容

大概是这样的:

export class DocumentsService {
  private _documents$ = new BehaviorSubject<Array<Document>>([]);
  public documents$: Observable<Array<Document>>;

  constructor(private http: HttpClient) { 
    this.documents$ = this._documents$.asObservable()
  }

  getDocuments(): Observable<any[]> {
    this.http.get<any[]>(`https://localhost:5001/docs`).switchmap(
      (response) => this._documents$.next(response)
    )
  }

  postDocument(item: any): Observable<any> {
    # update _documents$ here
  }

  putDocument(id: number, item: any): Observable<any> {
    # update _documents$ here
  }

  deleteDocument(id: number): Observable<any> {
    # update _documents$ here
  }
}

它应该会起作用。

这对你来说可能有点过头了,但我建议包括一家商店。每个CRUD操作都是一个单击即可分派的操作。请求由effects发送,您的组件仅从store中选择文档。@MoxxiManagarm,我认为向正在构建简单CRUD应用程序的新手建议状态管理选项是不合适的。谢谢您的建议,我通常使用强类型,但是对于这个问题,我将类型更改为
any
,以避免使这个问题复杂化。异步管道为您进行订阅。这就是使用异步管道的全部要点。请更新你的答案,这完全是错误的,因为我没有回答你问题中关于获取更新数据的部分。您可以从其他方法中调用此.getDocuments()。我将更新我的答案以显示。@Jean XavierRaynaud,请查看作者的原始postDocument、putDocument和deleteDocument方法。作者问题中的异步管道仅执行其CRUD应用程序的读取部分。@mikolajs,如果您想在出现错误时刷新数据,也可以在此用例中使用管道finalize。作者的postDocument,putDocument和deleteDocument方法在未订阅的情况下不会调用服务方法。请用更新后的组件部分更新您的答案。@j如果它们基本上都是琐碎的事情,只需从服务器读取响应,并在switchman或排气图中更新行为主题。
postDocument(项目:any):Observable
将不会在作者的当前消费组件中执行,因为它返回一个Observable,并且需要订阅<代码>postDocument():中的void
this.documents$ = this.documentsService.documents$