异步管道语法技巧

昨天,我们写过如何使用异步管道自动订阅和取消订阅从我们的观测数据。

当我教授这个话题时,人们通常至少有以下两种反对意见之一:

如果我还需要订阅的数据在我的Typescript代码?

首先,使用异步pipe似乎只允许您访问HTML模板中的数据。但事实并非如此,因为你仍然可以使用tap操作符来“监视”你的可观察对象,并从中获取数据。例如(完整例子):

              
              
.的名字$ = nameService.getName()。管(丝锥(<跨度class="hljs-function">的名字=><跨度class="hljs-keyword">这.的名字=的名字));
代码语言:<跨度class="shcb-language__name">打印稿<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">打印稿<跨度class="shcb-language__paren">)

然后在HTML模板中:

              
<<跨度class="hljs-name">p>异步管道的名称:{{Name $ | async}}<跨度class="hljs-tag">p>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

如果我需要从订阅中的对象中读取多个属性怎么办?

另一种说法是,你不想以这样的方式结束:

              
<<跨度class="hljs-name">p>名字:{{(用户$ | async)?。firstName}}<跨度class="hljs-tag">p><跨度class="hljs-tag"><<跨度class="hljs-name">p>姓氏:{{(用户$ | async)?。lastName}}<跨度class="hljs-tag">p>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

上面的代码很难阅读,每个属性都需要一个订阅。这本身就是一场灾难,因为每个订阅都可能触发来自服务器的相同数据的HTTP请求!

相反,您可以这样做,只使用一个订阅,将结果存储在一个局部变量中,然后在数据可用时呈现数据。此技术适用于任何结构指令,例如* ngIf* ngFor

              
<<跨度class="hljs-name">div*<跨度class="hljs-attr">ngIf=<跨度class="hljs-string">"user$ | async as user"><跨度class="hljs-tag"><<跨度class="hljs-name">p>名字:{{用户。firstName}}<跨度class="hljs-tag">p><跨度class="hljs-tag"><<跨度class="hljs-name">p>姓:{{用户。lastName}}<跨度class="hljs-tag">p><跨度class="hljs-tag">div>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

如果通过添加元素来适应订阅来更改DOM结构让您感到困扰,那么您可以使用ng-template相反,尽管这里的语法也可能有点令人不安:

              
<<跨度class="hljs-name">ng-template[<跨度class="hljs-attr">ngIf] =<跨度class="hljs-string">"user$ | async"<跨度class="hljs-attr">让用户><跨度class="hljs-tag"><<跨度class="hljs-name">p>名字:{{用户。firstName}}<跨度class="hljs-tag">p><跨度class="hljs-tag"><<跨度class="hljs-name">p>姓:{{用户。lastName}}<跨度class="hljs-tag">p><跨度class="hljs-tag">ng-template>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

好了,今天就到这里吧。明天,我们将看到我们如何做得比现在更好。

如何避免RxJs可观察对象的内存泄漏?

在大型Angular应用程序中,最容易陷入麻烦的方法是不取消订阅可观察对象会造成内存泄漏.虽然有不同的技术自动取消订阅可观察对象,一种方法更简洁、优雅,而且总体上是最防错的。

这个技巧就是使用异步从Angular框架。

为什么异步管这么厉害的工具?

  1. 首先,它自动订阅可观察对象,因此我们不再需要调用.subscribe ()
  2. 它返回来自该可观察对象的数据,在我们的组件需要显示最新数据时触发Angular的更改检测。
  3. 最后,当我们的组件被销毁时,它会自动从可观察对象中取消订阅。

所有这一切都只需要6个字符!(好吧,如果你想计算空白,可能会多一点):

              
<<跨度class="hljs-name">div>{{myObservable | async}}<跨度class="hljs-tag">div>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

异步如果我们不使用Pipe,它的工作方式与我们编写的代码完全相同(因此会反复重复,使代码库更大,从而使代码更慢)。

检查它的源代码在这里,您将看到它所做的一切都是实现ngOnDestroy取消订阅我们的可观察对象。

没有任何好的理由不使用异步管道,如果您认为您有一些理由,请继续关注我们的下一条消息,因为我们将介绍一些关于使用该管道的很好的提示和技巧。

日期管道默认格式和时区

日期管道是用Angular格式化日期的最方便的方法。然而,通常情况下,我们需要在整个应用程序中使用一致的日期格式,这意味着每次使用日期管道时都必须传递自定义格式:

              
<<跨度class="hljs-name">跨度>今天是{{今天|日期:'月/日/日'}}<跨度class="hljs-tag">跨度>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

当然,我们可以将该格式存储在一个常量中,并在每次使用管道时重用该常量,但这不是很方便。

幸运的是,从Angular 15开始,我们现在可以通过配置一个名为DATE_PIPE_DEFAULT_OPTIONS

它的工作原理是将以下代码添加到依赖注入配置(数组的供应商)app.modules.ts

              
提供者:[{<跨度class="hljs-attr">提供: DATE_PIPE_DEFAULT_OPTIONS,<跨度class="hljs-attr">useValue:{<跨度class="hljs-attr">dateFormat:<跨度class="hljs-string">“MM / dd / yy”}}]
代码语言:<跨度class="shcb-language__name">JavaScript<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">javascript<跨度class="shcb-language__paren">)

有了这样的配置,我们就可以在没有任何参数的情况下使用管道,并在整个应用程序中自动应用默认格式:

              
<<跨度class="hljs-name">跨度>今天是{{今天|日期}}<跨度class="hljs-tag">跨度>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

属性也可以自定义时区时区相同的属性DatePipeConfig对象。

使用JSON管道进行调试

我们都用过console.log调试我们的代码。在Angular中,有一个有趣的替代方案可以临时在我们的web页面上显示调试信息JSON管

主要用途如下:

              
<<跨度class="hljs-name">跨度>myData | json<跨度class="hljs-tag">跨度>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

中以JSON字符串的形式输出数据跨度元素,但它不会被格式化,所以JSON字符串可能很难阅读:

              
{<跨度class="hljs-string">“关系”:<跨度class="hljs-string">“友好的”,<跨度class="hljs-string">“象征”:<跨度class="hljs-string">“默认土地单位”,<跨度class="hljs-string">“雁行”:<跨度class="hljs-string">“没有”,<跨度class="hljs-string">“mod1”:<跨度class="hljs-string">“没有”,<跨度class="hljs-string">“mod2”:<跨度class="hljs-string">“没有”,<跨度class="hljs-string">“uniqueDesignation”:<跨度class="hljs-string">"",<跨度class="hljs-string">“higherFormation”:<跨度class="hljs-string">"",<跨度class="hljs-string">“reinforcedReduced”:<跨度class="hljs-string">"",<跨度class="hljs-string">“飞行”:<跨度class="hljs-literal">假,<跨度class="hljs-string">“活动”:<跨度class="hljs-literal">假,<跨度class="hljs-string">“安装”:<跨度class="hljs-literal">假,<跨度class="hljs-string">“工作组”:<跨度class="hljs-literal">假,<跨度class="hljs-string">“commandPost”:<跨度class="hljs-string">“没有”,<跨度class="hljs-string">“tacticalMissionTasks”:<跨度class="hljs-string">“没有”,<跨度class="hljs-string">“类型”:<跨度class="hljs-string">“土地单位”}
代码语言:<跨度class="shcb-language__name">JavaScript<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">javascript<跨度class="shcb-language__paren">)

相反,下面的语法工作得更好:

              
<<跨度class="hljs-name">精准医疗>myData | json<跨度class="hljs-tag">精准医疗>
代码语言:<跨度class="shcb-language__name">HTML、XML<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">xml<跨度class="shcb-language__paren">)

精准医疗HTML标签代表“精准医疗格式化”内容。因此,该标记将保留任何空白、新行和制表符,这使得读取JSON数据变得更容易:

              
{<跨度class="hljs-string">“关系”:<跨度class="hljs-string">“友好的”,<跨度class="hljs-string">“象征”:<跨度class="hljs-string">“默认土地单位”,<跨度class="hljs-string">“雁行”:<跨度class="hljs-string">“没有”,<跨度class="hljs-string">“mod1”:<跨度class="hljs-string">“没有”,<跨度class="hljs-string">“mod2”:<跨度class="hljs-string">“没有”}
代码语言:<跨度class="shcb-language__name">JavaScript<跨度class="shcb-language__paren">(<跨度class="shcb-language__slug">javascript<跨度class="shcb-language__paren">)

这是一个简单的技巧,但在调试使用复杂JSON结构的代码时节省了大量时间。