问题 在SPA中制作干净的id空间有哪些常见的解决方案?


情况:几个开发人员在SPA的不同部分/模块上远程工作。 因此,他们可能会意外地引入相同的HTML元素 id。在最终组合之前,有哪些常见方法可以避免这种情况(如果可能的话,不拒绝使用id)?

我的浅见猜测:

  • 预安排 id 所有的名字(有点荒谬,但......)

  • 结构名称与架构,例如为 app/collection/model 奉献一个像这样的名字 app-collection-model

  • 拒绝使用 id一般情况下还是仅用于大型模块?


7744
2017-07-11 01:57


起源

SPA - 单页应用程序 - Anthony Sottile
我猜团队之间的对话是更好的方式 - felipekm
不要将ID用于任何事情。 - PW Kad
目前我正在开发一个巨大的SPA,我们决定使用包名+“普通”名称作为id。 - GuyT
最正确的答案是测试和 continuous integration 喜欢 stridercd.com 其余的归结为偏好,鼓励少用id。肯定的名字很重要,但惯例只是一个好的组织,并不是万无一失的。 - Dylan


答案:


如果您使用不同的ID一次又一次地编写相同的HTML代码,那么您做错了。

如今,有许多方法可以创建不需要ID的可重用HTML组件。

我认为错了:

对于大项目(涉及多个团队或大量观点),我不认为一次又一次地写原始HTML是一个好主意。

这种方法意味着:重复代码和将来重构的痛苦(想想2年内应用程序的重新设计)。这就是为什么有那么多的UI框架有助于创建可重用的组件,其中HTML只编写一次并在任何地方使用。最后,您的应用程序将需要几个组件:表,弹出窗口,窗体,子菜单,选项卡..

目标是创建一个框架,其中包含开发人员可用于创建视图的组件,而无需实际编写任何HTML代码。

我的观点是:HTML代码应该只在大项目中编写一次而且只编写一次。显然它写入一次的事实并不意味着它只能在一个地方呈现,它可以在应用程序的任何地方。

我的建议:

数据绑定救援!

如果无法做出重大改变, 惯例 是要走的路。你建议的那个可能有意义,但要小心,每次你改变结构时,所有的ID都是错的!


2
2017-07-14 16:56



我不能完全同意你的看法。 If you are writing the same HTML code again and again with different IDs you are doing something wrong. 这并非总是如此。如果您有多个具有相同字段的屏幕,则您可能具有相同的ID(屏幕1:关系,屏幕2:订单..两者都将具有字段 name 在它和可能相同的身份)。 - GuyT
@GuyT我更新了我的答案以澄清我的想法。对不起,如果我没有解释自己! - margabit
现在我同意你:)。在当前项目中,我们甚至不使用HTML(仅JS),但让DOJO进行标记。 - GuyT
:) Exacly!就是这样,可重复使用的组件将UI问题集中到一个地方。 - margabit
另一个事实是,更容易向客户销售。您可以使用他们可以切换到另一个框架而没有问题的参数;) - GuyT


除非绝对必要,否则尽量避免使用ID。从CSS或JS引用HTML片段时,坚持使用类而不是ID。你的CSS和JS不应该真正关心(关注点的分离)关于DOM的确切结构或者页面上有多少'foo'元素...他们只想在任何'foo'元素上设置样式或行为哪些课程非常适合。

你无法完全避免使用ID ...例如,标记HTML以支持可访问性将需要使用ID ...但这些ID和对它们的引用将被限制在同一HTML文件(或SPA模板)中所以如果你觉得他们中的任何一个可能发生冲突,请继续使他们冗长/冗长以避免冲突。

当然这不是 完全 解决你的问题。通过专注于课程,你可以避免生成无效HTML的可能性,一切都在爆炸,但你仍然存在协作问题,即确保人们不会出乎意料地通过使用相同的类名来搞砸彼此的工作。在许多情况下,你实际上  跨页面使用的相同类。如果您想确保没有冲突(例如,在网站上有共同的按钮或排版样式),您可以将每个HTML模板包装成类似的东西 <div class='name-of-this-template'>...</div> 然后在CSS / JS选择器中,将选择器的范围仅匹配在该模板中: .name-of-this-template .a-class-used-within-the-template


3
2017-07-13 02:32



+1用于注意与类名冲突可能发生的问题。 FWIW,我通过确定容器(例如,如你所建议的父包装上的类)或者是合格的ID来处理这个问题,比如 document-editor-save-button (这是额外的打字,但消除了最多的歧义)。如果需要,我还会动态生成ID前缀,并将其添加到元素的元素/引用之前。这消除了所有歧义。 - Tim Medora


当一个项目由多个团队并行开发时,其成功的关键因素是团队之间的沟通。

团队应该按照设定的时间间隔聚在一起讨论跨领域的问题(例如,ID的命名策略)。例如,如果使用Scrum敏捷开发方法,团队将在“Scrum of Scrums”会议中定期会面以讨论此类问题。

通过交谈,团队将能够就最适合正在开发的组件的命名约定(并记录约定的约定以供将来参考)达成一致 那时候 (当我在那个时候说得最好的时候,我的意思是最简单,最容易阅读,同时避免任何命名冲突)。因此,你的建议是在工作正在同时进行时“预先安排”id,这并不像你想象的那么荒谬!


2
2017-07-14 00:33



我认为项目范围的命名模式不适合scrum会议。如果您要通过命名模式完全解决问题,那很好但是这些约定需要是一个记录的工件(可能甚至用代码检查),因为如果有人在5年之后搞砸了代码由不同的人维护,重复的ID可能导致可能难以捕获的错误。 - Robert Levy
@RobertLevy“Scrum of Scrum”会议的目的是协调并行团队之间的发展。如果团队在同一个域中工作(即创建UI组件),则关于ID的对话是相关的。这些会议的结果将是演变和文档(是的,Scrum流程确实创建文档)使用的命名约定。我完全同意标准文件很重要。我的回答是强调,我认为标准应该随着时间的推移而发展/发展。 - Ben Smith


在我的一个项目中,我们遇到了这个问题。我们的快速解决方案和下一代码维护/重构周期的一部分是使用可识别的html元素继承JavaScript容器的属性和模板。

让我详细介绍一下。

  • 我们用 Backbone.Marionette 同 Handlebars 模板。对于每个模板,我们都有一个与每个模板相关联的自定义View类(我们将Backbone.Marionette扩展为具有更多功能)。此View类具有ID和UI元素。 UI元素在模板中编译,因此除非我们在视图类本身中更改UI元素名称,否则我们永远不必更改HTML。因此,我们可以改变我们想要的UI元素的Id,并且不会影响任何事情(几乎)。

  • 由于我们为每个窗口小部件使用视图,因此您可以确定它们的标识符或名称,或者您想要调用它,是唯一的。我们在UI元素中使用它作为我们Id的基础。这允许我们重用Widget。

  • _.uniqueId() 来自Underscore库也用于CollectionViews。

希望我帮忙,欢呼!


2
2017-07-17 22:00





如果您的代码(问题)非常大,并且您无法重构它,您可以尝试在每次提交之前验证您的css / html以查找重复ID。但对于非常糟糕的情况,这是可能的答案。

好的解决方案 - 使用像bem这样的工具http://bem.info/


2
2017-07-18 16:22



任何文章bem比其他乐器更好? - Nik Terentyev
我没有使用bem,但我使用了一些想法:我只使用没有ID和困难选择器的长名称类。它给了我良好的浏览器性能,代码可读和树形结构(使用SCSS 3.3 - jsbin.com/vohekupa/2/edit)。对于bem,oocss等都是如此。完整的bem说“将每个小部件放在不同的文件夹中”,以保证文件系统级别上的不同名称。 BEM是Yandex的(俄罗斯谷歌)项目,该项目旨在让数千名开发人员聚集在一起并为许多问题提供答案。它有一个很好的社区和各种乐器,但它是怪物。有关更多信息:vimeo.com/38346573 - Aleksey


给每个开发人员(或模块)或唯一的id前缀。

例如,如果开发人员X正在开发模块Y,那么他的前缀应该是其中之一 x_y_ 要么 xy_
假设 x_ 被选中,他创建的ID看起来像 x_foox_barx_thing 等等

优点:

  1. 避免碰撞ID(显然)。

  2. 在集成模块时,ID清楚地表明它们属于何处。
    这提供了更好的可读性,这是原始的!!

  3. 写作 x_something 足够刺激,以避免过度使用ID。
    与此同时,没有人会使用它们并不那么令人恼火。

缺点:

  1. 它会让至少一些开发者不高兴。 (有些人比其他人灵活性差。)
    一种可能的补救措施是要求他们将ID更改为 x_ 形成,
    仅在整合之前,即在开发结束之前。
    在此之前,他们可能会使用无前缀的ID名称。

  2. 一些模块 依赖于其他模块。在整合之前
    必须共享和正确使用适当的ID名称。
    虽然这可能需要一些额外的时间,但它(希望)是值得的。


2
2017-07-18 21:55



在开发结束时(在投入生产之前)改变一些东西对我来说听起来不是一个好主意。你很容易忽视某些东西。对于集成测试,已经需要使用命名空间ID。 - Bergi
我同意。通过“在集成期间”,我必须意味着“在集成之前”。我会解决问题。谢谢。 - Sumukh Barve


我更愿意看到id仅用于指定模块,小部件,主要部分等。这将导致较少的id一般,并且大多数命名由业务逻辑创建。您还最终使用某种本地化层次结构构建类和标记,如: #specialWidget h3 {} #specialWidget p {} 你只需选择你的处理程序 - $('#specialWidget .some-btn').click() 而且从不喜欢 $('#someBtn').click() 因为它只是变得凌乱而且过于具体。

过去,测试和持续集成是捕捉这样的事情的最佳选择。


1
2017-07-14 00:11



为什么你会使用ID而不是类?如果你想拥有2,会发生什么 specialWidget在页面上?此外,还有重要的地方 必须 使用ID单个元素,例如在实现可访问性时,甚至只是指定 for 属性 label 元素。 - Robert Levy
我并不是说暗示没有必要通过id指定的情况。只是总的来说,人们倾向于过度使用它们,减少数量和维护惯例的简单方法是将它们推向层次结构。你肯定会使用任何倍数的类,并且有些库会强制你使用id。您还需要这些案例的约定。 - Dylan