我们知道面向个人用户(to Customer, 简称 2C)软件和面向企业级用户(to Business, 简称 2B)的软件,在设计和实现上都存在一些区别,比如个人软件通常注重直观的用户界面和简单易用的设计,其中用户体验是关键,因为个人软件的目标是满足个人用户的需求和偏好。想想我们每天都在刷的抖音和头条,当然也包括掘金这种软件。
而 2B 企业软件更注重效率和工作流程的优化。其界面可能相对较为复杂,设计目标是提高员工的生产力。同时,企业软件更注重满足企业流程的特定需求,可能具有高度定制的功能,即产品标准里所谓的 Extensibility.
我目前工作在一个使用 Angular 开发的电商 Storefront 开源项目上,项目的 Github 地址如下,项目代号为 Spartacus.
下图是这个 Storefront 编译并使用 ng serve
启动后,看到默认的 homepage.
![](https://img.haomeiwen.com/i2085791/8fe06ef0f0877149.png)
既然是面向企业的 Angular 应用,就必然存在着定制化需求,比如很难想象电商用户使用 Spartacus 开发出 Storefront 之后,期望这个 Storefront 的外观都千篇一律。
本文通过一个实际的例子来讲解。
同其他 Angular 应用一样,Spartacus Storefront UI 的最小粒度是 Angular Component. 在 Angular 中,Component(组件)是构建用户界面的基本构建块之一。它是一个自包含的、可复用的代码单元,负责控制视图的一部分。Angular 应用的架构是基于组件的,通过组件化开发,可以更好地组织和维护代码。
Angular 组件的核心概念包括:
-
模板(Template): 模板定义了组件的视图,使用 Angular 的模板语法来描述如何渲染和显示数据。模板中可以包含HTML、Angular Directive(指令)和数据绑定。
-
类(Class): 组件的类包含了与模板相关的业务逻辑。这里定义了属性和方法,用于处理用户输入、管理组件状态等。
-
装饰器(Decorator): 装饰器是一个特殊的类型,用于将类标记为 Angular 组件。
@Component
装饰器用于告诉 Angular 如何处理这个类。 -
元数据(Metadata): 装饰器中的元数据提供了关于组件的信息,如选择器(selector)、模板和样式文件的路径等。
可以说只要找准 Angular Component,就把握住了 Angular 应用 Extensibility 实现的命脉。
基于 Angular Component 替换的 Extensibility 思路,即根据要扩展的 UI,找到原本实现这个 UI 界面的 Angular Component,将其替换成客户自开发的 Customer Component,然后把自开发逻辑,实现在这个自开发 Component 里即可。
下面看一个实战案例。
假设我想对下图高亮区域, 即 Storefront 购物车(Cart)页面的产品列表部分,进行二次开发。
![](https://img.haomeiwen.com/i2085791/7c0f8d3df61a5d17.png)
在 Chrome 开发者工具里,找到上图实现页面的 Angular 组件对应的 selector:cx-cart-details.
![](https://img.haomeiwen.com/i2085791/a21cf0182413c99a.png)
根据找到的 selector cx-cart-details , 作为关键字,在 partacus 源代码里进行搜索。
每个 Angular Component 同其 selector 具有一一对应关系,因此我们找到了 Component selector cx-cart-details, 也就找到了组件名称:CartDetailsComponent:
![](https://img.haomeiwen.com/i2085791/3f81837e1e7b26c2.png)
在 Spartacus 的默认实现里,Commerce Cloud 后台的 Cart 模型 CartComponent,映射的 Angular Component,正好是我们之前找到的 CartDetailsComponent:
![](https://img.haomeiwen.com/i2085791/cc102014904dd1eb.png)
所以接下来,我们要做的事情:
- 创建一个新的 Angular Component,扩展自标准 Angular Component CartDetailsComponent.
如下图所示,我给这个新建的 Component 取名为 MyCartComponent,其 selector 为 app-my-cart.
![](https://img.haomeiwen.com/i2085791/eba2d40647bf616d.png)
- 新建的 MyCartComponent 扩展自标准的 CartDetailsComponent,既可重用后者已有的业务逻辑,也可以编写新的业务逻辑。
而 UI 界面的二次开发,在该 Component 对应的模板文件,my-cart.component.html 里实现。
为简单起见,在我自定义的 MyCartComponent 里,我仅仅打印出添加到购物车里的产品名称,然后首尾加上两个一级标题。
![](https://img.haomeiwen.com/i2085791/bcf0abef0ab90b54.png)
MyCartComponent 开发完毕后,将其映射到 Commerce Cloud 后台 CMS 模型 CartComponent 上。
下图第83行~89行的语义是,通过 ConfigModule.withConfig 方法,定义了一个优先级比 Spartacus 标准配置优先级更高的客户配置,该配置的内容是一条映射记录,告诉 Spartacus 框架:当页面要渲染 Commerce Cloud 名为 CartComponent 的模型时,请使用我开发的 MyCartComponent 进行页面绘制。
![](https://img.haomeiwen.com/i2085791/0d02141deefd53b7.png)
上图第 90 行的代码,用到了 ConfigModule.withConfig
方法。
在 Spartacus 中,ConfigModule.withConfig
是一个非常重要的方法,它可以用于提供应用程序配置。这个方法接收一个配置对象,该对象定义了应用程序的各种设定,例如:路由设定、功能设定或其它特性设定等。这个方法会将这个配置对象合并到应用程序的总配置中。
这个二次开发最后的效果如下:
![](https://img.haomeiwen.com/i2085791/1ada0faf647aee36.png)
在生成的 HTML 源代码里,我们自定义的 Angular Component 的 selector app-my-cart, 取代了 Spartacus 标准 Cart Component的 selector cx-cart-details.
![](https://img.haomeiwen.com/i2085791/a6c18ed87292b645.png)
以上就是基于 Angular Component 替换的 Extensibility 支持的一个实际案例。
笔者后续会在社区分享更多企业级 Angular 应用 Extensibility 的实现方式。
网友评论