将角消防员图书馆放置 - II
怎么入门文章编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《将角消防员图书馆放置 - II》,涉及到,有需要的可以收藏一下
>以前,我们创建了自己的firestore getters来返回适当的观察力,从而将诺言转变为可冷观察的诺言。今天,让我们继续使用其他命令,以正确地映射我们的数据。
>映射数据
>现在我们不依赖rxfire返回映射的文档id,我们将创建自己的转换器。
“ firestore有一个内置的converter withconverter to conconter tor map to and firestore。不,谢谢。我们将从这里拿走。getdoc()返回具有id的文档napshot,以及上述数据()。 getdocs()返回带有docs数组的querysnapshot,除其他外,这是返回的documentsnapshot对象。我们的类别模型现在看起来像这样:
// category.model
// mapping new instance
export interface icategory {
name: string | null;
id: string | null;
key?: string;
}
// static class or export functions, it's a designers choice
export class category {
public static newinstance(data: querydocumentsnapshot): icategory {
if (data === null) {
return null;
}
const d = data.data();
return {
id: data.id,
name: d['name'],
key: d['key']
};
}
// receives querysnapshot and maps out the `data() ` and id
public static newinstances(data: querysnapshot): icategory[] {
// read docs array
return data.docs.map(n => category.newinstance(n));
}
}
因此,现在的服务调用看起来像这样:
// category.service getcategories(params: iwhere[] = []): observable{ // ... return from(getdocs(_query)).pipe( map((res: querysnapshot) => { // here map return category.newinstances(res); }) ); } getcategory(id: string): observable { return from(getdoc(doc(this.db, 'categories', id))).pipe( map((res: documentsnapshot) => { // map return category.newinstance(res); }), ); }
>让我们看看什么adddoc()返回。>
创建文档
>我创建了一个带有名称和键的快速表单,添加类别,以及一个服务呼叫以创建类别:
// components/categories.list
addnew() {
// read form:
const newcat: partial = this.fg.value;
this.categoryservice.createcategory(newcat).subscribe({
next: (res) => {
// the category list should be updated here
console.log(res);
}
});
}
>该服务有望返回可观察到的,以下内容可能无法将其删除,返回的对象是一个文档重新率,仅是对具有id创建的文档的引用。
// category.service createcategory(category: partial): observable { return from(adddoc(collection(this.db, 'categories'), category)).pipe( map(res => { // i have nothing but id! return {...category, id: res.id}; }) ); }
>可能看起来不错,但是我不希望在不浏览映射器的情况下直接使用id,解决方案可以像单独的映射器一样简单,或者我们可以稍微适应newinstance // category.model
// adjust newinstance to accept partial category
public static newinstance(data: documentsnapshot | partial
然后,在服务呼叫中,我们通过返回的id
// category.service createcategory(category: partial): observable { return from(adddoc(collection(this.db, 'categories'), category)).pipe( map(res => { // update to pass category and res.id return category.newinstance(category, res.id); }), ); }
firestore语法的奇怪案例
>以下方法是如此相同,如果您不区分它们,您可能会在50岁之前失去头发。因此,我决定列出它们,然后忘记它们。
doc(collection(this.db,'cantories'))返回新生成的id >
setdoc(_document_reference,{... newcategory},选项)设置文档数据,并在文档参考中保存提供的id
adddoc(collection(this.db,'cantories'),{... newcategory});添加带有自动生成id的文档(这是doc(collection ...)然后setdoc())- >的快捷方式
- updatedoc(doc(this.db,'categories','staust_id'),partial_category)这会更新现有文档(doc(db ...)的快捷键(db ...),然后使用现有id)进行setdoc()
- >从前两个开始激起了混乱,它们看起来是如此相似,但是它们是不同的
-
// find document reference, or create it with new id const categoryref = doc(this.db, 'categories', '_somedocumentreferenceid'); // create a document reference with auto generated id const categoryref = doc(collection(this.db, 'categories'));
现在,返回的参考文档可用于创建实际文档,或对其进行更新。因此,预计将通过setdoc - 成功
- >如果文档不存在wit合并设置为true,它将创建一个带有部分数据的新文档。不好。小心。
// then use the returned reference to setdoc, to add a new document
setdoc(categoryref, {name: 'bubbles', key: 'bubbles'});
// pass partial document with options: merge to partially update an existing document
setdoc(existingcategoryref, {name: 'bubble'}, {merge: true});
>
// add a new documnet with a new generated id
adddoc(collection(this.db, 'categories'), {name: 'bubbles', key: 'bubbles'});
// update and existing document, this will throw an error if non existent
updatedoc(existingcategoryref, {name: 'bubbles'})
出于插图目的,这是创建新类别的另一种方法
// an alternative way to create createcategory(category: partial更新文档): observable { // new auto generated id const ref = doc(collection(this.db, 'categories')); return from(setdoc(ref, category)).pipe( map(_ => { // response is void, id is in original ref return category.newinstance(category, ref.id); }) ); }
>在上面的构建中,我为类别详细信息创建了一个快速表单以允许更新。我仍然会通过所有字段,但是我们总是可以通过部分字段。
>
// category.sevice // id must be passed in category updatecategory(category: partial这是概念的证明,有一些方法可以拧紧松动的末端,例如强迫id通过,检查不存在的文档,返回不同的数据形状等。): observable { return from(updatedoc(doc(this.db, 'categories', category.id), category)).pipe( map(_ => { // response is void // why do we do this? because you never know in the future what other changes you might need to make before returning return category.newinstance(category); }) ); }
>
使用它,收集表格,并捕获id:
// categories/list.component
update(category: icategory) {
// gather field values
const cat: partial = this.ufg.value;
// make sure the id is passed
this.categoryservice.updatecategory({...cat, id: category.id}).subscribe({
next: (res) => {
console.log(res); // this has the same category after update
}
});
}
删除文档
这是直截了当的,我们可能会选择退还布尔值以获得成功。
>
// category.sevice deletecategory(id: string): observable{ return from(deletedoc(doc(this.db, 'categories', id))).pipe( // response is void, but we might want to differentiate failures later map(_ => true) ); }
我们只是通过传递id
来称其为
// category/list.component
delete(category: icategory) {
this.categoryservice.deletecategory(category.id).subscribe({
next: (res) => {
console.log('success!', res);
}
});
}
>没有直截了当的批量删除方式。让我们继续前进。
负责任地查询
>我们创建了一个iwher模型,以允许将任何查询传递到我们的类别列表。但是,我们应该控制在模型中查询的字段,并保护我们的组件免受现场变化的影响。我们还应该控制可以询问的内容,以及如何始终领先于火箱上的任何隐藏价格。
// where.model
// the param fields object (yes its plural)
export interface ifieldoptions {
label?: string; // exmaple
key?: string;
// other example fields
month?: date;
recent?: boolean;
maxprice?: number;
}
// map fields to where conditions of the proper firestore keys
export const maplistoptions = (options?: ifieldoptions): iwhere[] => {
let c: any[] = [];
if (!options) return [];
if (options.label) {
// mapping label to name
c.push({ fieldpath: 'name', opstr: '==', value: options.label });
}
if(options.key) {
c.push({ fieldpath: 'key', opstr: '==', value: options.key });
}
// maxprice is a less than or equal operator
if (options.maxprice) {
c.push({ fieldpath: 'price', opstr: '<=', value: options.maxprice });
}
if (options.month) {
// to implement, push only data of the same month
c.push(...mapmonth(options.month));
}
if (options.recent) {
const lastweek = new date();
lastweek.setdate(lastweek.getdate() - 7);
// things that happened since last week:
c.push({ fieldpath: 'date', opstr: '>=', value: lastweek });
}
return c;
}
我们服务的更改就像这样>
// category.sevice // accept options of specific fields getcategories(params?: ifieldoptions): observable这是如何以最高价格获取一组文档的示例:{ // translate fields to where: const _where: any[] = (mapfieldoptions(fieldoptions)) .map(n => where(n.fieldpath, n.opstr, n.value)); // pass the where to query const _query = query(collection(this.db, this._url), ..._where); // ... getdocs }
// example usage
something$ = someservice.getlist({maxprice: 344});
这更有意义。我添加了一个日期示例,请注意,即使firestore日期为type tymestamp,在javascript日期上的操作正常。该示例的想法是说明组件不应该真正知道实现的详细信息,因此获得“最新文档”,例如应该像这样的>
// example
something$ = someservice.getlist({recent: true});
另一个示例是获取日期,firestore直接处理javascript日期:// where.model
const mapmonth = (month: date): iwhere[] => {
const from = new date(month);
const to = new date(month);
from.setdate(1);
from.sethours(0, 0, 0, 0);
to.setmonth(to.getmonth() + 1);
to.sethours(0, 0, 0, 0); // the edge of next month, is last day this month
let c: iwhere[] = [
{ fieldpath: 'date', opstr: '>=', value: from },
{ fieldpath: 'date', opstr: '<=', value: to }
];
return c;
};
时间戳
firestore参考时间戳。
>
// somemodel
// use timestamp class to map from and to dates
const jsdate = new date();
// adddoc with
const newdata = {
fbdate: timestamp.fromdate(jsdate)
}
// documentsnapshot returns data() with date field, the type is timestamp
// use todate to convert to js date
return data['fbdate'].todate();
firestore lite
firebase为firestore提供了简单crud的lite版本,到目前为止,我们仅使用了lite版本中的那些。我更改了所有
导入{...}来自'@angular/fire/firestore';
导入{...}来自'@angular/fire/firestore/lite';
>构建块的确很小。我个人项目中减少的主要部分从502 kb下降到352 kb。
拦截
>使用httpclient,我们使用了截距函数来添加加载效果,那么我们如何使用解决方案来做到这一点?我们可以将所有呼叫调查到一个照顾它的http服务。我们的新服务应该与此有关:
// http.service
@injectable({ providedin: 'root' })
export class httpservice {
public run(fn: observable): observable {
// show loader here
showloader();
// return function as is
return fn
.pipe(
// hide loader
finalize(() => hideloader()),
// debug and catcherrors as well here
);
}
}
然后在服务中
// category.service private httpservice = inject(httpservice); getcategories(params?: iwhere[]): observable{ // ... // wrap in run return this.httpservice.run(from(getdocs(q)).pipe( map((res: querysnapshot) => { return category.newinstances(res); }) )); }
>上面的一个设计问题是类型检查的丢失,因为内部函数返回可观察到的
修复
// http.service // ... public run(fn: observable ): observable { // ... }
然后这样称呼:>
// category.service return this.httpService.run>查看我们先前使用状态管理创建的加载效果。我们需要的只是注入州服务,然后呼叫显示和隐藏。这使用了良好的ol'rxjs,我调查了信号,看不到它如何替换rxj,而不会造成大混乱。可能是一个罚款星期二。(from(getDocs(q)).pipe( map((res: QuerySnapshot) => { return Category.NewInstances(res); }) ));
就是这样。在50岁之前不要丢发头发。
你上火了吗?继续说话。还没有结束。
资源
stackblitz project
>在angular
中使用rxj创建负载效果
- 将angular fire firestore库使用-ii- sekrab车库
- 角燃箱炸弹群。以前,我们创建了自己的firestore获取器,以返回适当的观察力,从而将诺言转变为可感冒的诺言。今天,让我们继续使用其他命令,以正确地映射我们的数据。
garage.sekrab.com
了解VUE ND VUE 3之间的差异
- 上一篇
- 了解VUE ND VUE 3之间的差异
- 下一篇
- Golang环境深处潜水:从零到英雄
-
- 文章 · 前端 | 4天前 | 前端 · 性能优化 · css · Core Web Vitals · 渲染性能 · 前端 渲染性能 CSS性能 CLS content-visibility contain-intrinsic-size Layout
- 前端长页面渲染卡顿怎么排查:用 content-visibility 跳过离屏区块
- 430浏览 收藏
-
- 文章 · 前端 | 1星期前 | 前端 · javascript · AbortController · 表单提交 · AbortController 旧响应覆盖 前端重复提交 loading锁 fetch取消 按钮防抖
- 前端按钮重复提交怎么办:loading 锁和 AbortController 最小配方
- 442浏览 收藏
-
- 文章 · 前端 | 1星期前 | 前端 · 缓存 · Service Worker · 白屏 · 发布故障 · 缓存策略 前端白屏 Service Worker CacheStorage 资源404 发布回滚
- 前端发布后白屏复盘:Service Worker 缓存旧入口导致 JS 资源 404
- 469浏览 收藏
-
- 文章 · 前端 | 1星期前 | 前端开发 · localStorage · 表格配置 · 用户偏好 · 后台系统 · 用户偏好 localStorage 前端表格 列配置 可见列 列宽保存
- 前端表格列设置刷新后丢失怎么办:可见列、列宽和顺序这样保存
- 351浏览 收藏
-
- 文章 · 前端 | 1星期前 | 前端 · 接口排查 · 运维手册 · 性能告警 · 前端 AbortController 接口超时 Network瀑布图 降级回滚 线上告警
- 前端接口超时告警运行手册:从瀑布图到降级回滚
- 287浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ljg-skills
- ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
- 4427次使用
-
- MELO音乐
- MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
- 4079次使用
-
- UniScribe
- UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
- 4064次使用
-
- 剧云
- 剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
- 4253次使用
-
- 万象有声
- 万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
- 4223次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- CSS变量简化按钮悬停效果技巧
- 2026-05-31 501浏览
-
- JavaScript符号类型详解与应用
- 2026-05-31 501浏览
-
- HTML剪贴板复制粘贴怎么用
- 2026-05-26 501浏览
-
- data-*属性详解:HTML数据存储与DOM操作技巧
- 2026-05-25 501浏览

