未定义:第三个布尔值

Avatar of Kushagra Gour
Kushagra Gour

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费信用额度!

我想在我的一个项目中实现一个通知消息,类似于您在 Google Docs 中保存文档时看到的。换句话说,每次进行更改时,都会显示一条消息,指示文档正在保存。然后,一旦更改保存,消息将变为:“所有更改已保存在云端硬盘中。”

让我们看看如何使用布尔值来实现这一点,但实际上涵盖了三种可能的状态。这绝对不是唯一的方法,坦率地说,我甚至不确定这是否是最佳方法。无论如何,它对我有用。

这是一个“正在保存...”状态的示例

Screenshot of the Google Docs header with a message that says the document is saving.
“正在保存”通知在每次对文档进行更改时显示。

...以及“已保存”状态

Screenshot of the the message reading All Changes Saved after saving has completed.
“已保存”通知在更改或一组更改完成后显示。

使用Boolean值来定义状态是我的第一反应。我可以有一个名为isSaving的变量,并使用它在我的模板中呈现条件字符串,如下所示

let isSaving;

...以及在模板中

<span>{{ isSaving ? ‘Saving...’ : ‘All changes saved’ }}</span>

现在,每当我们开始保存时,我们将值设置为true,然后在没有保存正在进行时将其设置为false。很简单,对吧?

但是,这里存在一个问题,它有点用户体验问题。默认消息呈现为“所有更改已保存”。当用户最初访问页面时,没有进行保存,即使从未发生过保存,我们也会收到“已保存”消息。我更希望在第一次更改触发第一个“正在保存”消息之前不显示任何内容。

这需要在我们的变量isSaving中添加第三种状态。现在问题变成了:我们将值更改为字符串变量作为三种状态之一吗?我们可以这样做,但是如果我们可以在当前布尔变量本身中获得第三种状态怎么办?

isSaving可以取两个值:truefalse。但在我们声明语句let isSaving;之后,直接的值是什么?它是undefined,因为任何变量的值在声明时都是undefined,除非为其分配了某个值。太好了!我们可以利用该初始undefined值来发挥我们的优势……但是,这需要我们稍微更改一下在模板中编写条件的方式。

我们正在使用的三元运算符对于任何无法转换为true的内容都计算为第二个表达式。undefinedfalse的值都不是true,因此对于三元运算符而言,它们都解析为false。即使是if/else语句也会以类似的方式工作,因为else针对任何不是true的内容进行评估。但我们希望区分undefinedfalse。这可以通过显式检查false值来修复,如下所示

<span>
{{ isSaving === true ? 
  ‘Saving...’ : 
  (isSaving === false ? ‘All changes saved’: ‘’) 
}}
</span>

我们现在正在严格检查truefalse值。这使得我们的三元运算符稍微嵌套了一些,难以阅读。如果我们的模板支持if/else语句,那么我们可以像这样重构模板

<span>
{% if isSaving === true %}
  Saving...
{% elseif isSaving === false %}
  All changes saved
{% endif %}
</span>

啊哈!当变量既不是true也不是false时,不会呈现任何内容——这正是我们想要的!