在复杂 UI 更改中使用功能标志
Using feature flags in complex UI changes
为了简化问题,假设有一个 HTML 页面及其 CSS 和 JS 文件。没有服务器。
现在请求在这个简单的网站 UI 中切换功能 on/off。
问题是,例如,一项新功能意味着更改 HTML
结构以添加新组件,因此现在 HTML 有点不同。
此外,页面本身的 CSS
需要更改以支持新组件。当然,还有 javascript
代码需要更改以适应对 HTML..
所做的更改
当然,如果这个组件完全是 "isolated" 并且只有 它是自己的 CSS、javascript 和 html模板文件,它要容易得多,但它确实需要更改它周围的东西,它所在页面的 HTML/CSS/JS
。
如何将如此复杂的过程简化为简单的"feature toggle"?
此外,为了将复杂性提升到一个新的水平,这个新功能可能需要更改项目中使用的某些库版本,但在切换功能时这是另一个难度级别。但是让我们忽略这部分讨论是因为我对上面提到的事情比较感兴趣
我认为复制标志的最佳方法是创建一个 JSON 文件,其中包含您想要隐藏的 ID。然后只需读入 Javascript FileReader (https://developer.mozilla.org/en-US/docs/Web/API/FileReader),解析 JSON,并隐藏映射的错误 ID。
假设您的可切换功能是以下输入框:
<input id="input_box"/>
<input id="input_box2"/>
您的文本文件将包含以下内容:
{
input_box: false,
input_box2: true
}
input_box 将被隐藏,而 input_box2 将被显示。这似乎是启用标志的唯一方法,除非你想把它放在 URL.
我想出了以下方法:
系统基本上由以下部分组成:
- index.html(所有内容都加载到的基本 HTML 入口点)
- HTML 个模板文件
- SCSS 文件
- 架构相关 javascript 文件
- javascript 控制器(有点像页面。控制页面事件以及在其中使用哪些组件)
- javascript 个组件(假设表格、网格、树形菜单、面包屑...)
home.html
模板示例:
<div class='col'>
<component class='line-chart'></component>
<component class='table'></component>
</div>
<div class='col'>
<component class='bar-chart'></component>
</div>
我做的步骤(简化):
创建一种在 UI:
中切换功能 on/off 的方法
创建一个架构(system/app-related)javascript 文件,其任务是创建一个下拉菜单,用户可以选择要切换的功能,结果保存在 本地存储。
将下拉列表附加到页面。
当用户选择一个功能时,重新加载页面并刷新后,从 localstorage 读取功能并将它们保存到 属性 下的架构状态对象"features",待会用到
创建功能:"home-v2"
所以,我正在 Master 分支上工作(就像老板一样),我想在某些页面中进行一些大的更改,添加一些组件并移动其他组件周围现有的。我所做的是:
- 复制页面
_home.scss
的 SCSS 文件并重命名为 _feature-home-v2--home.scss
(它将使用 globbing 通过 main.scss
自动导入)
- 复制页面
home.html
的模板文件并重命名为feature-home-v2--home.html
- 导入将用于页面控制器 javascript 文件的 javascript 组件文件。
写一些 if
语句
这是 "ugly" 部分,我必须在其中根据每个功能设置要执行的操作。因此,对于我的新示例功能 home-v2,我需要做一些事情:
- 转到主页 javascript 控制器文件并转到我加载 HTML 模板的行,并检查 [=89= 的应用程序状态 "features" 对象]
像这样:
var templateName = `home`;
if( app.state.features['v2--home'] )
templateName = `feature-home-v2--` + templateName;
- 现在该页面使用了不同的 HTML 结构,它看起来与默认主页相似,但具有更多的组件并且一些组件的顺序不同:
feature-home-v2--home.html
模板示例:
<component class='breadcrumbs'></component>
<div class='col'>
<component class='table'></component>
<component class='line-chart'></component>
</div>
<div class='col'>
<component class='pie-chart'></component>
</div>
我现在可以将导入的控制器加载到它们所在的位置(之前它们可能已经导入但未在页面上初始化)。
对过程的思考:
- 在 Sublime 中点击
ctrl-p
并开始输入 feature-
将仅显示与功能相关的文件。
- 从构建过程中产生更大的输出,并且不为每个功能使用不同的 GIT 分支。
- 应该合并功能 quickly/discarded 这样代码就不会因为很多功能而变得混乱。
- 在单个分支上使用所有功能可以快速 adding/removing 轻松自定义下拉菜单 checkbox/radio。
- GIT 提交必须记住根据所处理的功能命名,以维护 GIT 使用合理名称的顺序。
- 对于更复杂的更改,可能需要克隆和重命名其他文件,甚至是顶层控制器本身。
为了简化问题,假设有一个 HTML 页面及其 CSS 和 JS 文件。没有服务器。
现在请求在这个简单的网站 UI 中切换功能 on/off。
问题是,例如,一项新功能意味着更改 HTML
结构以添加新组件,因此现在 HTML 有点不同。
此外,页面本身的 CSS
需要更改以支持新组件。当然,还有 javascript
代码需要更改以适应对 HTML..
当然,如果这个组件完全是 "isolated" 并且只有 它是自己的 CSS、javascript 和 html模板文件,它要容易得多,但它确实需要更改它周围的东西,它所在页面的 HTML/CSS/JS
。
如何将如此复杂的过程简化为简单的"feature toggle"?
此外,为了将复杂性提升到一个新的水平,这个新功能可能需要更改项目中使用的某些库版本,但在切换功能时这是另一个难度级别。但是让我们忽略这部分讨论是因为我对上面提到的事情比较感兴趣
我认为复制标志的最佳方法是创建一个 JSON 文件,其中包含您想要隐藏的 ID。然后只需读入 Javascript FileReader (https://developer.mozilla.org/en-US/docs/Web/API/FileReader),解析 JSON,并隐藏映射的错误 ID。
假设您的可切换功能是以下输入框:
<input id="input_box"/>
<input id="input_box2"/>
您的文本文件将包含以下内容:
{
input_box: false,
input_box2: true
}
input_box 将被隐藏,而 input_box2 将被显示。这似乎是启用标志的唯一方法,除非你想把它放在 URL.
我想出了以下方法:
系统基本上由以下部分组成:
- index.html(所有内容都加载到的基本 HTML 入口点)
- HTML 个模板文件
- SCSS 文件
- 架构相关 javascript 文件
- javascript 控制器(有点像页面。控制页面事件以及在其中使用哪些组件)
- javascript 个组件(假设表格、网格、树形菜单、面包屑...)
home.html
模板示例:
<div class='col'>
<component class='line-chart'></component>
<component class='table'></component>
</div>
<div class='col'>
<component class='bar-chart'></component>
</div>
我做的步骤(简化):
创建一种在 UI:
中切换功能 on/off 的方法创建一个架构(system/app-related)javascript 文件,其任务是创建一个下拉菜单,用户可以选择要切换的功能,结果保存在 本地存储。
将下拉列表附加到页面。
当用户选择一个功能时,重新加载页面并刷新后,从 localstorage 读取功能并将它们保存到 属性 下的架构状态对象"features",待会用到
创建功能:"home-v2"
所以,我正在 Master 分支上工作(就像老板一样),我想在某些页面中进行一些大的更改,添加一些组件并移动其他组件周围现有的。我所做的是:
- 复制页面
_home.scss
的 SCSS 文件并重命名为_feature-home-v2--home.scss
(它将使用 globbing 通过main.scss
自动导入) - 复制页面
home.html
的模板文件并重命名为feature-home-v2--home.html
- 导入将用于页面控制器 javascript 文件的 javascript 组件文件。
写一些 if
语句
这是 "ugly" 部分,我必须在其中根据每个功能设置要执行的操作。因此,对于我的新示例功能 home-v2,我需要做一些事情:
- 转到主页 javascript 控制器文件并转到我加载 HTML 模板的行,并检查 [=89= 的应用程序状态 "features" 对象]
像这样:
var templateName = `home`;
if( app.state.features['v2--home'] )
templateName = `feature-home-v2--` + templateName;
- 现在该页面使用了不同的 HTML 结构,它看起来与默认主页相似,但具有更多的组件并且一些组件的顺序不同:
feature-home-v2--home.html
模板示例:
<component class='breadcrumbs'></component>
<div class='col'>
<component class='table'></component>
<component class='line-chart'></component>
</div>
<div class='col'>
<component class='pie-chart'></component>
</div>
我现在可以将导入的控制器加载到它们所在的位置(之前它们可能已经导入但未在页面上初始化)。
对过程的思考:
- 在 Sublime 中点击
ctrl-p
并开始输入feature-
将仅显示与功能相关的文件。 - 从构建过程中产生更大的输出,并且不为每个功能使用不同的 GIT 分支。
- 应该合并功能 quickly/discarded 这样代码就不会因为很多功能而变得混乱。
- 在单个分支上使用所有功能可以快速 adding/removing 轻松自定义下拉菜单 checkbox/radio。
- GIT 提交必须记住根据所处理的功能命名,以维护 GIT 使用合理名称的顺序。
- 对于更复杂的更改,可能需要克隆和重命名其他文件,甚至是顶层控制器本身。