我对使用Javascript编写HTML的良好实践存有疑问。
我想出了一个想法(可能不是第一个,但是找不到明确的参考),将某些元素标记为在可用时加载某些数据的候选者(在一些用户交互之后)。让我举例说明:
假设我有一个返回以下内容的请求:
GET /animals/dog
{
name: "Gutemberg",
race: "doberman",
age: "2y"
}
我写的代码将响应中的字段绑定到可以加载此类值的候选元素。 例如:根据上面的请求,我可以使用以下标记:
<input name="dog-name-field" data-load-dog-name type="text"/>
<input name="dog-age-hid" data-load-dog-age type="hidden"/>
每个标记都会收到属性值,因为它被标记为这样做的候选者 - 当所有内容都执行时,dog-name-field
将具有值“Gutemberg”。每次重新加载请求时都会发生这种情况。现在,我只获取我搜索过的数据类型(“ dog ”),将其与属性“ name / age ”连接起来,形成属性{{1并为具有此类属性的每个人设置一个值。
我觉得属性不应该像那样使用,但我不知道有任何真正的缺点。由于我无法找到这种方法的明确名称,我想要一些指导。
这种技术有名字吗?这是一种不好的做法吗?如果是这样,为什么?
PS: 为了遵守SO的良好做法,我希望答案是参考指导的,而不是仅仅基于意见。如果没有提供参考,请让我们有一个可靠的,很好描述的例子。
答案 0 :(得分:1)
这称为绑定。有时数据绑定,有时模板绑定。
虽然语法各不相同,但各种框架都为此提供了机制。
AngularJS示例:
<input ng-model="dog.name" />
Knockout示例:
<input data-bind="textInput: dog.name" />
React示例:
<input value={this.state.dog.name} />
这些都是非常流行的框架/库,所以我认为可以说它不被认为是不好的做法。与您的方法的主要区别在于,它们使用属性的值来指定对模型的引用(即属性的“dog.name”部分),同时将引用放在属性名称中。在实践中,这主要是风格问题。将引用与“标记”分开(即“数据加载”)可能更具可读性。
答案 1 :(得分:1)
我觉得属性不应该像那样使用
让我们看一下自定义数据属性的用途:
自定义数据属性旨在存储私有的自定义数据 页面或应用程序,没有更合适的 属性或元素。这些属性不适合使用 与使用属性的站点无关的软件。
(来自w3.org)
因此,使用data-attributes
是否适合&#34;在您的情况下,取决于您的需求:如果DOM API没有提供更好的属性,那么它是合适的。
如果您只需要选择一些元素来更改textContent
,那么您有两个更合适/更简单的选项:
1)如果您的元素在文档中是唯一的,则使用id
属性
id
全局属性定义必须具有的唯一标识符(ID) 在整个文件中是独一无二的其目的是识别元素 链接(使用片段标识符),脚本或样式时 (使用CSS)。
(来自MDN上的id)
2)如果您的元素将在文档中的多个实例中使用,请使用class
属性
class
全局属性是以空格分隔的类的列表 元素。类允许CSS和Javascript选择和访问 通过类选择器或DOM等函数的特定元素 方法document.getElementsByClassName。
(来自MDN上的class)
正如@Supr在他的回答中所说,你所做的是data-binding的一个非常简单的实现。 数据绑定可能涉及比您目前所做的更复杂的事情;例如,你可能想:
使用代表您的业务模型的Javascript对象保持您的UI同步,而不是直接注入来自Ajax调用的数据,
更新其他属性(值,样式),而不仅仅是innerHTML或textContent,
更新您的商业模式以响应用户界面上的更改(two way data binding)
要实现所有这些功能,简单的id
和class
选择器是不够的,这就是为什么实现数据绑定的框架(如KnockoutJS或AngularJS)使用更灵活的{{1}相反(AngularJS实际上使用自己的data-*
属性,但允许使用替代的ng-*
语法来使用HTML验证工具。)
数据属性允许描述更复杂的绑定:
data-ng-*
检查KnockoutJS documentation上述代码的含义,它与此示例无关,只是想象用<input data-bind="visible: editing, value: name, hasFocus: editing" />
es或class
来描述,但它不会非常方便。
<强> TL; DR 强>
如果您不打算实施更复杂的功能,则可能需要使用id
和class
。