如何在角度应用程序中正确保存从 api 获取的数据,以便在我们再次访问该页面时不会发出请求,例如返回?



我想保存从API获取的一些数据,这样用户在重新访问页面时就不必重新修改内容了。此外,它有助于保持滚动位置(不过我不知道这是否是正确的方法(。

目前,我使用BehaviourSubject将其保存在服务中,并且只有在服务没有任何值的情况下才发出请求,如果有,我只需获得该值,而不是进行HTTP调用。并在用户注销时清除该服务。

这是代码

blogs_storage.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { Blog } from './blog.model';
@Injectable({ providedIn: 'root' })
export class BlogStorageService {
private blogs = new BehaviorSubject<Blog[]>(null);
private userBlogs = new BehaviorSubject<Blog[]>(null);
clearStorage() {
this.blogs.next(null);
this.userBlogs.next(null);
}
getBlogs(): BehaviorSubject<Blog[]> {
return this.blogs;
}
getUserBlogs(): BehaviorSubject<Blog[]> {
return this.userBlogs;
}
storeUserBlogs(blogs: Blog[]): void {
this.userBlogs.next(blogs);
}
storeBlogs(blogs: Blog[]): void {
this.blogs.next(blogs);
}
}

blogs.service.ts


import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, catchError, exhaustMap, tap, throwError } from 'rxjs';
import { Blog, NewBlog } from './blog.model';
import { BlogStorageService } from './blogs-storage.service';
@Injectable({ providedIn: 'root' })
export class BlogService {
constructor(
private http: HttpClient,
private blogStorage: BlogStorageService
) {}
fetchAllBlogs() {
const blogs: Blog[] = this.blogStorage.getBlogs().getValue();
if (blogs) {
return this.blogStorage.getBlogs().asObservable();
} else {
return this.http.get<{ data: Blog[]; status: number }>('blogs').pipe(
tap((blogs) => {
this.blogStorage.storeBlogs(blogs.data);
}),
exhaustMap(() => {
return this.blogStorage.getBlogs().asObservable();
})
);
}
}
fetchUserBlogs() {
const blogs: Blog[] = this.blogStorage.getUserBlogs().getValue();
if (blogs) {
return this.blogStorage.getUserBlogs().asObservable();
} else {
return this.http
.get<{ data: Blog[]; status: number }>('users/blogs')
.pipe(
tap((blogs) => {
this.blogStorage.storeUserBlogs(blogs.data);
}),
exhaustMap(() => {
return this.blogStorage.getUserBlogs().asObservable();
})
);
}
}
fetchBlogBySlug(slug: string) {
return this.http.get<{ data: Blog; status: number }>(`blogs/${slug}`);
}
fetchCategoriesList() {
return this.http.get<{
data: { _id: string; title: string; slug: string }[];
status: number;
}>('blogs/category-list');
}
postblog(data: NewBlog) {
return this.http.post('blogs/create', data);
}
getSavedBlogs() {
return this.http.get<{ data: Blog[]; status: number }>('users/savedblogs');
}
saveBlog(slug: string, alreadySaved: boolean) {
return this.http.put(
`users/savedblogs/${slug}/${alreadySaved ? 'unsave' : 'save'}`,
{}
);
}
}

注销

logout() {
this.user = null;
this.isAuth.next(false);
this.blogStorage.storeUserBlogs(null);
localStorage.removeItem('userData');
this.router.navigate(['/auth/login']);
}

这样清除数据安全吗?还有什么更好的方法可以实现这种行为吗?

我是一个刚接触角的人,所以如果我的实现有缺陷,请告诉我。

我使用了类似的方法,使用了BehaviorSubject。但是,与其有一个单独的BehaviorSubject,不如尝试使用

BehaviorSubject例如:-

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { Blog } from './blog.model';
@Injectable({ providedIn: 'root' })
export class StorageService {
private storeData = new Map<StorageKey, BehaviourSubject>();
clearData(key: StorageKey) {
if(storeData.get(key)){
this.storeData.get(key).next(null)
}
}
getData(key: StorageKey): BehaviorSubject<any> {
return this.userBlogs.get(key);
}
storeData(key: StorageKey,data: any): void {
if(!this.storeData.get(key)){
this.storeData.add(key, new BehaviourSubject<any>())
}
this.userBlogs.next(blogs);
}
}
public enum StorageKey{
BLOGS = 'BLOGS',
USER_BLOGS = 'USER_BLOGS'
}

另外,如果你不想花时间开发自己的框架,你可以使用NgRx 实现类似的状态维护能力

在blogs_storage.service.ts中创建公共可观察性,而不是返回BehaviorSubject。然后,在使用服务的地方,订阅可观察性。

这是一个很好的视频,做了很好的解释。它很长,但你可以以1.25或1.5的速度观看。

https://youtu.be/HnNytR32Otk

最新更新