浅谈 Angular 应用前端消息显示机制的一个实际需求

简介: 浅谈 Angular 应用前端消息显示机制的一个实际需求

笔者在一个开源的名叫 Spartacus 的电商框架项目上,已经工作三年多了。

这是这个开源项目在 Github 上的仓库,本项目基于 Angular 框架开发而成:https://github.com/SAP/spartacus

本文分享笔者近日完成的一个关于消息显示的需求实现的一些经验。

这个需求来自 StackOverflow 社区上一位 Spartacus 的使用者的一个定制化实现时遇到的问题:

这个需求的背景是,客户在 SAP 电商云的产品明细页面,可以留下自己的评论,点击 Submit 按钮提交。

提交之后,能看到“谢谢评论”的提示消息。

客户定制化需求是:不执行这个默认的消息显示逻辑,即不显示消息,而是执行其他逻辑,比如短信通知或邮件通知。

目前 Spartacus 默认显示 谢谢评论的代码如下:

showGlobalMessageOnPostProductReviewSuccess$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(ProductActions.POST_PRODUCT_REVIEW_SUCCESS),
        tap(() => {
          this.globalMessageService.add(
            { key: 'productReview.thankYouForReview' },
            GlobalMessageType.MSG_TYPE_CONFIRMATION
          );
        })
      ),
    { dispatch: false }
  );

“感谢评论”的消息文本 ID 为 productReview.thankYouForReview,在 ProductReviewEffects 接收到 POST_PRODUCT_REVIEW_SUCCESS 这个 Action 之后通过 MessageService 显示到 UI 上。

一种最常规的二次开发思路就是,继承 SAP Commerce Cloud UI 标准发布的 ProductReviewEffects 类,重载其接收到 POST_PRODUCT_REVIEW_SUCCESS 之后的实现代码,将调用 MessageService 抛出感谢评论的代码删除掉即可。

然而 SAP Commerce Cloud UI 发布的所有 Effects 实现类都是不可扩展的,因此这条思路行不通。

SAP 电商云 Spartacus UI,同 Commerce 后台交互的逻辑:

Spartacus 同 Commerce 系统的通信,通过 HTTP 协议调用 OCC API 完成。Connector 是 HTTP调用的发起者,维护了静态的配置信息,即 API endpoint.

比如,从 Commerce 系统读取产品主数据,读取的字段列表以 url 参数的形式出现在 API endpoint 里。这些字段列表可以在 Connector 的静态配置点里进行配置。

Connector 并不会直接同 Commerce 交互,而是把请求转发给 Adapter,具体通信由 Adapter 完成,Connector 只负责调度 Adapter. Spartacus 发布的 Adapter 默认使用 OCC Module,即 Commerce 标准的 OCC Restful API,但是客户也可以实现自己的 Adapter,连接 Commerce 之外的其他后台系统。

Connector 将 Adapter 取回的数据交给 NgRx Store 结构统一管理,后者的复杂度被 Facade 层所隐藏,而Spartacus UI 组件只会同 Facade 层交互,进行数据绑定和页面展示。这体现了关注点分离的设计原则。

为了实现该需求,我们需要深入了解下图红色高亮区域即 NgRx Store 和 SAP Spartacus Connector 交互的细节。

NgRx 是 Angular 基于 RxJs 的一个响应式状态管理库,包含下列核心概念,笔者会结合 SAP Commerce Cloud UI 对 NgRx 的实际使用情况来举例说明。

  • Action:其实就是编程领域的事件的别名。SAP Commerce Cloud UI 组件,能响应用户操作,通过组件的 Service 实例,投递出相应的 Action. Action 投递方和 Action 接收方是解耦的,彼此感知不到对方。
    下图是 SAP 电商云产品明细页面评论区域的 Submit 按钮被点击之后,对应的 Service 类抛出 PostProductReview Action 的代码:

  • ProductActions.PostProductReview 是 NgRx Action 的一个子类,type 字段为 POST_PRODUCT_REVIEW,构造函数的参数 payload,定义了调用 Commerce OCC API 持久化用户评论需要传递的数据结构:

  • Effects:SAP Commerce Cloud UI Action 的接收方之一。下图 Effects 代码的语义是:接收类型为 POST_PRODUCT_REVIEW 的 Action(第46行),调用前文介绍的 Connector,向 Commerce 后台发起 OCC API 调用(第49行),根据 API 返回结果,分别投递评论保存成功或失败的 Action:
  • PostProductReviewSuccess(第53行)
  • PostProductReviewFail(第56行)

  • Store:Angular 应用维护在内存中的存储结构,存放了 SAP Commerce Cloud UI 所有组件的运行时数据。每当 Effects 调用 Commerce OCC API 拿到新的数据时,调用 Reducer,将增量数据填充到 Store 中去。
  • Reducer:本质上是一个有限状态自动机,每当收到代表来自 Commerce 后台的数据发生变化的 Action 时,状态机驱动对应的 Reducer, 根据新的 Action 包含的负载,对 Store 中的数据进行调整。
    例如产品明细页面第一次渲染时,Effects 需要从 Commerce 后台读取所有的评论数据。读取成功后,抛出 LOAD_PRODUCT_REVIEWS_SUCCESS Action. 下图的 ProductReviewsReducer 接收到该 Action,从其 payload 中解析出实际评论数据并返回。这些返回的数据会被 NgRx 框架接收,并合并到 Store 中去。

  • Selector:纯函数,作为应用程序从 NgRx Store 中读取最新数据的接口。

理清楚 SAP Commerce Cloud UI 使用 NgRx 进行状态管理的细节之后,对于文章开头的客户定制化需求,也就不难实现了。

既然下图所示的 SAP Commerce Cloud UI 标准的 Effects 无法扩展,我们注意到 UI 组件的 Service 层,才是所有事件流的起始点,因此可以实现新的 Service,来替换 SAP 电商云 UI 标准的 Service,然后基于该定制化 Service,实现配套的 Effects 和 Action.

如此一来,标准的和用户评论相关的逻辑流(如下图 1-2-3 所示)将不会再得到执行,取而代之的是我们自己定制化的执行流,如下图 A-B-C 所示,其中蓝色的图例均为 Partners 需要开发的定制化代码。

这个解决方案的简要介绍:

(1) 创建新的 Action CustPostProductReview,CustPostProductReviewSuccess 和 CustPostProductReviewFail. 其实就是在标准的实现类之前,添加 Cust 的前缀。

(2) 创建新的 CustProductReviewService,继承标准的 ProductReviewService. 重载其 add 方法,抛出新的 CustPostProductReview Action.

(3) 新建 CustProductReviewsEffects,接收新的 Action CUST_POST_PRODUCT_REVIEW(第25行),仍旧调用 Connector 将用户评论持久化到 Commerce 后台(第28行),然后抛出新的 Action CustPostProductReviewSucess.

自定义 Effect 接收到新的 Action CUST_POST_PRODUCT_REVIEW_SUCCESS 之后,就可以进行自定义逻辑编写。

(4)将自定义的 Effect 和 Service 实现,通过 Angular 依赖注入框架,配置到对应的 Module 中。

本需求在 SAP Spartacus 3.1 版本测试通过。

总结

本文通过一个实际需求的实现案例,详细介绍了 Angular Ngrx 里 Effect,Connector,Adapter,Reducer,Selector 和 Store 等概念的交互关系,希望对需要实现类似功能的同行有所帮助。


相关文章
|
4天前
|
存储 前端开发 JavaScript
第六章(原理篇) 微前端间的通信机制
第六章(原理篇) 微前端间的通信机制
|
4天前
|
JavaScript 前端开发 架构师
Angular进阶:理解RxJS在Angular应用中的高效运用
RxJS(Reactive Extensions for JavaScript)是JavaScript的一个响应式编程库,特别适用于处理异步数据流。
10 0
|
5天前
|
JavaScript 前端开发
Angular.js 应用中数据模式的删除操作实现
Angular.js 应用中数据模式的删除操作实现
16 0
|
1天前
|
前端开发 Java Go
从前端到后端:构建现代化Web应用的技术演进
本文探讨了从前端到后端的技术演进,介绍了前端、后端以及多种编程语言,如Java、Python、C、PHP和Go,以及数据库在构建现代化Web应用中的应用。通过深入剖析各个技术领域的发展和应用,读者将对构建高效、可扩展、安全的Web应用有更深入的理解。
|
4天前
|
前端开发 Java Go
从前端到后端:构建现代化Web应用的技术实践
本文将介绍如何通过前端和后端技术相结合,构建现代化Web应用的技术实践。我们将探讨前端开发、后端架构以及多种编程语言(如Java、Python、C、PHP、Go)在构建高效、可扩展的Web应用中的应用。
|
4天前
|
前端开发
前端路由机制实现hash-history
前端路由机制实现hash-history
8 1
|
4天前
|
前端开发 JavaScript 测试技术
第八章(应用场景篇) 中大型项目的解构:从单体应用到微前端
第八章(应用场景篇) 中大型项目的解构:从单体应用到微前端
|
4天前
|
Web App开发 前端开发 JavaScript
构建跨浏览器兼容的前端应用:技术实践与挑战
【5月更文挑战第16天】构建跨浏览器兼容的前端应用是应对浏览器差异和多样性的挑战。使用现代框架(如React、Vue)能自动转换代码,编写可移植的Web标准代码,结合浏览器兼容性测试工具和Polyfill解决旧浏览器支持问题。关注浏览器更新,应对性能、API差异和样式问题,采用渐进增强、条件判断和CSS Reset策略确保应用在各种浏览器上运行良好。
|
5天前
|
资源调度 JavaScript 编译器
显式指定 npm 作为创建 Angular 应用时的包管理器
显式指定 npm 作为创建 Angular 应用时的包管理器
15 1
|
5天前
|
JavaScript 前端开发
关于 Angular.js 应用里的 $scope.$apply()
关于 Angular.js 应用里的 $scope.$apply()
30 8