通过项目中的实际例子,介绍 LocalStorage 在 Angular 开发中的使用场景

简介: 通过项目中的实际例子,介绍 LocalStorage 在 Angular 开发中的使用场景

笔者之前在掘金社区的技术文章,介绍过自己项目组中负责开发的一款基于 Angular 的电商 SDK:

本文笔者会分享自己项目过程中,在设计这款 SDK 时使用 Web 开发领域的 LocalStorage 技术来实现的一个功能。

用户访问 Storefront 的 homepage,可以在 Language 的下拉菜单里,选择语言:

比如下图是语言切换成中文的效果:

同样还支持货币单位的切换:

客户的需求是,更改的这些设置,在关闭浏览器之后,仍然能够生效。意思是下次重新打开浏览器,Storefront homepage 仍然按照之前的设置去加载。

为此,我们团队采取的实现方式是,利用 Web 开发领域中的 LocalStorage 技术,来持久化用户指定的 Language 和货币单位的更改。

Local Storage 技术概述

Local Storage 技术是一种在Web 浏览器中用于客户端数据存储的机制。它允许 Web 应用程序在用户的本地浏览器上存储键值对形式的数据,这样用户在关闭浏览器窗口或页面后,数据仍然可以保留。这为开发者提供了一种在客户端持久保存数据的简单方式,而不必依赖于服务器。

我们在 Chrome 开发者工具 Application 面板里,可以清晰观察到这些 Key Value 键值对:

Local Storage 是Web Storage API 的一部分,与 Session Storage 不同,Local Storage 的数据在关闭浏览器后仍然存在。它使用键值对的形式存储数据,其中键和值都是字符串。该技术基于域名,即同一域名下的所有页面共享相同的 Local Storage

使用方式也非常简单直观,使用其提供的 get 和 set API 即可。

在 JavaScript 中,通过 localStorage 对象来访问和操作 Local Storage。以下是一些基本的 localStorage 操作:

存储数据:

// 存储数据
localStorage.setItem('username', 'John');
// 存储数字
localStorage.setItem('userAge', 25);

读取数据:

// 读取数据
const username = localStorage.getItem('username');
const userAge = localStorage.getItem('userAge');

删除数据:

// 删除数据
localStorage.removeItem('username');

清空所有数据:

// 清空所有数据
localStorage.clear();

我们项目组当时选择用 LocalStorage 技术来实现用户需求,也是基于了如下考虑:

  1. 持久性: 数据在浏览器关闭后仍然存在,适用于长期保存用户偏好设置等信息,比如我们项目中客户对于 Language 和货币单位的持久化需求。
  2. 容量:Local Storage 允许存储较大数量的数据(通常至少5MB),相对于 Cookie 的4KB而言,具备更大的容量,我们用来存储两个字符串值,可以说是绰绰有余。
  3. 简易性: 使用简单的键值对操作,易于理解和实现。

尽管 LocalStorage 数据存储在客户端,但是我们存储的仅仅是 Language 和货币单位,所以不存在敏感信息。

Local Storage 技术的项目实战

首先我们在 state-config.ts 文件里定义了 StorageSyncType 的枚举值:

可以看到目前我们打算支持 LocalStorage 和 SessionStorage 两种方式,方便 SDK 的 consumer 自己切换。

而 getStorage 函数用来封装获取 LocalStorage API 的行为:

export function getStorage(
  storageType: StorageSyncType,
  winRef: WindowRef
): Storage | undefined {
  let storage: Storage | undefined;
  switch (storageType) {
    case StorageSyncType.LOCAL_STORAGE: {
      storage = winRef.localStorage;
      break;
    }
    case StorageSyncType.SESSION_STORAGE: {
      storage = winRef.sessionStorage;
      break;
    }
    case StorageSyncType.NO_STORAGE: {
      storage = undefined;
      break;
    }
    default: {
      storage = winRef.sessionStorage;
    }
  }

这里 storage API 从依赖注入参数的 winReflocalStorage 或者 sessionStorage 字段里读取。

这两个字段都是全局对象 window 里的标准属性之一。

本文之前介绍的 LocalStorage API 就位于 localStorage 字段的原型链上,如下图高亮区域所示:

language 字段的 LocalStorage 读取

用户重新打开浏览器时,需要从 LocalStorage 里将存储的 language 字段值读取出来。

这个场景通过下图的 readFromStorage 函数实现:

export function readFromStorage(storage: Storage, key: string): unknown {
  if (isSsr(storage)) {
    return;
  }
  const storageValue = storage.getItem(key);
  if (!storageValue) {
    return;
  }
  return JSON.parse(storageValue);
}

逻辑很直接,首先判断是否是在 SSR 环境下,如果是就直接返回。因为按照笔者这篇文章的介绍,用户的个性化设置和私有数据页面,比如购物车,WishList 等,不应该被 Angular 服务器端渲染考虑,所以我们代码里如果 isSsr 检测函数返回 true,直接返回;否则调用 storage 的 API 即 getItem 返回浏览器 LocalStorage 里的存储值。

下面是调试器里的截图:

language 字段的 LocalStorage 的写入

当用户在 Storefront 界面上用下拉菜单更换 Language 字段值时,会调用 browser-storage.ts 里的 persistToStorage 方法:

我们可以看到这个方法里调用代码第 44 行的 setItem,将 Angular UI 上用户选定的值写入到 LocalStorage 里。

下拉菜单的实现位于 site-context-selector.component.html 文件内部。当用户切换下拉菜单值的时候,触发第 3 行 select 元素的 change 事件。

事件的处理函数主体就只有一个 active = $any($event).target.value 的赋值操作,这会触发定义在 active 属性上的 set 方法:

set 方法里调用 this.componentService.setActive(value, this.context),这个函数调用最终把执行投递到 storage.setItem(configKey, JSON.stringify(value)) 上去:

总结

在 Local Storage 出现之前,客户端数据存储主要依赖于 cookies。但是,cookies 存在许多不足,比如存储空间有限(通常只有 4KB),数据在每次 HTTP 请求时都会被发送到服务器,这会消耗更多的带宽。相比之下,Local Storage 提供了更大的存储空间(通常是 5MB),并且数据只存储在客户端,不会被发送到服务器。这使得 Local Storage 成为一种更有效的客户端数据存储方式。

本文介绍了笔者在实际 Angular 开发项目中使用 Local Storage 来持久化用户个性化选择的一个案例,希望能帮助到需要实现类似功能的开发者们。

相关文章
|
2月前
|
API 开发者 UED
PrimeFaces:JSF的魔法衣橱,解锁UI设计的无限可能!
【8月更文挑战第31天】本文介绍如何结合 JSF(JavaServer Faces)和 PrimeFaces 构建美观且功能强大的现代用户界面。PrimeFaces 提供丰富的 UI 组件库,包括按钮、输入框、数据网格等,支持现代 Web 标准,简化界面开发。文章通过具体示例展示如何使用 `<p:inputText>` 和 `<p:calendar>` 等组件创建用户表单,并用 `<p:dataTable>` 展示数据集合,提升 JSF 应用的易用性和开发效率。
36 0
|
2月前
|
前端开发 Java UED
JSF遇上Material Design:一场视觉革命,如何让传统Java Web应用焕发新生?
【8月更文挑战第31天】在当前的Web开发领域,用户体验和界面美观性至关重要。Google推出的Material Design凭借其独特的动画、鲜艳的颜色和简洁的布局广受好评。将其应用于JavaServer Faces(JSF)项目,能显著提升应用的现代感和用户交互体验。本文介绍如何通过PrimeFaces等组件库在JSF应用中实现Material Design风格,包括添加依赖、使用组件及响应式布局等步骤,为用户提供美观且功能丰富的界面。
34 0
|
2月前
|
前端开发 大数据 数据库
🔥大数据洪流下的决战:JSF 表格组件如何做到毫秒级响应?揭秘背后的性能魔法!💪
【8月更文挑战第31天】在 Web 应用中,表格组件常用于展示和操作数据,但在大数据量下性能会成瓶颈。本文介绍在 JavaServer Faces(JSF)中优化表格组件的方法,包括数据处理、分页及懒加载等技术。通过后端分页或懒加载按需加载数据,减少不必要的数据加载和优化数据库查询,并利用缓存机制减少数据库访问次数,从而提高表格组件的响应速度和整体性能。掌握这些最佳实践对开发高性能 JSF 应用至关重要。
45 0
|
2月前
|
前端开发 安全 开发者
JSF文件上传,让Web应用如虎添翼!一招实现文件上传,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,文件上传是重要功能之一。JSF(JavaServer Faces)框架提供了强大的文件上传支持,简化了开发流程。本文将介绍JSF文件上传的基本步骤:创建前端表单、处理上传文件的后端Action类、将文件保存到服务器指定目录以及返回结果页面。通过示例代码,我们将展示如何利用JSF实现文件上传功能,包括使用`h:inputFile`控件和`ManagedBean`处理上传逻辑。此外,JSF文件上传还具备类型安全、解耦合和灵活性等优点,有助于提升程序的健壮性和可维护性。
28 0
|
2月前
|
开发者 Java 存储
JSF 与 CDI 携手共进,紧跟技术热点,激发开发者情感共鸣,开启高效开发新征程
【8月更文挑战第31天】JavaServer Faces (JSF) 与 Contexts and Dependency Injection (CDI) 在 Java EE 领域中紧密协作,助力开发者高效构建现代 Web 应用。JSF 凭借其丰富的组件库和页面导航功能受到青睐,而 CDI 则优雅地管理对象生命周期并实现依赖注入。两者结合,不仅简化了复杂企业应用的开发,还实现了松耦合架构,增强了代码的灵活性、可维护性和可扩展性。通过示例展示了如何利用 CDI 将业务服务对象注入 JSF Managed Bean,以及如何在不同页面间共享数据,突显了这一组合的强大功能。
33 0
|
2月前
|
开发者 安全 SQL
JSF安全卫士:打造铜墙铁壁,抵御Web攻击的钢铁防线!
【8月更文挑战第31天】在构建Web应用时,安全性至关重要。JavaServer Faces (JSF)作为流行的Java Web框架,需防范如XSS、CSRF及SQL注入等攻击。本文详细介绍了如何在JSF应用中实施安全措施,包括严格验证用户输入、使用安全编码实践、实施内容安全策略(CSP)及使用CSRF tokens等。通过示例代码和最佳实践,帮助开发者构建更安全的应用,保护用户数据和系统资源。
39 0
|
2月前
|
前端开发 API 开发者
JSF与RESTful服务的完美邂逅:如何打造符合现代Web潮流的数据交互新体验
【8月更文挑战第31天】随着互联网技术的发展,RESTful架构风格因其实现简便与无状态特性而在Web服务构建中日益流行。本文探讨如何结合JavaServer Faces (JSF) 和 JAX-RS 构建RESTful API,展示从前端到后端分离的完整解决方案。通过定义资源类、配置 `web.xml` 文件以及使用依赖注入等步骤,演示了在JSF项目中实现RESTful服务的具体过程,为Java开发者提供了实用指南。
32 0
|
2月前
|
开发者 C# C++
揭秘:如何轻松驾驭Uno Platform,用C#和XAML打造跨平台神器——一步步打造你的高性能WebAssembly应用!
【8月更文挑战第31天】Uno Platform 是一个跨平台应用程序框架,支持使用 C# 和 XAML 创建多平台应用,包括 Web。通过编译为 WebAssembly,Uno Platform 可实现在 Web 上运行高性能、接近原生体验的应用。本文介绍如何构建高效的 WebAssembly 应用:首先确保安装最新版本的 Visual Studio 或 VS Code 并配置 Uno Platform 开发环境;接着创建新的 Uno Platform 项目;然后通过安装工具链并使用 Uno WebAssembly CLI 编译应用;最后添加示例代码并测试应用。
55 0
|
2月前
|
前端开发 开发者 安全
JSF支付功能大揭秘:探索如何在Java世界中实现安全无缝的在线支付体验
【8月更文挑战第31天】在电子商务和在线交易日益普及的今天,实现在线支付功能已成为许多Web应用的必备需求。JavaServer Faces (JSF) 作为一种流行的Java Web框架,提供了丰富的组件和工具来构建用户界面,包括与支付网关集成以实现在线支付。支付网关是处理信用卡和借记卡支付的系统,在商家和银行之间起到桥梁作用。本文将探讨如何使用JSF与支付网关集成,以及实现在线支付功能时需要考虑的关键点
36 0
|
2月前
|
开发者 前端开发 开发框架
JSF与移动应用,开启全新交互体验!让你的Web应用轻松征服移动设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,移动设备的普及使得构建移动友好的应用变得至关重要。尽管JSF(JavaServer Faces)主要用于Web应用开发,但结合Bootstrap等前端框架,也能实现优秀的移动交互体验。本文探讨如何在JSF应用中实现移动友好性,并通过示例代码展示具体实现方法。使用Bootstrap的响应式布局和组件可以确保JSF页面在移动设备上自适应,并提供友好的表单输入和提交体验。尽管JSF存在组件库较小和学习成本较高等局限性,但合理利用其特性仍能显著提升用户体验。通过不断学习和实践,开发者可以更好地掌握JSF应用的移动友好性,为Web应用开发贡献力量。
39 0
下一篇
无影云桌面