我正在测试jQuery的data()
方法,它看起来非常强大。这实际上是用于测试我将要进行单元测试的工具(通过用双引号替换单引号来解析JSON元素)。
var test = $('#test');
console.log(test.data('table[data-table-values]'));

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="test" data-table-values="'{'header': ['value1', 'value2']}'"></table>
&#13;
返回undefined
。但是根据我的理解,这应该是返回选择器的内容,在这种情况下应该是:'{'header': ['value1', 'value2']}'
我错过了什么吗?
编辑:作为参考我正在测试执行此操作的函数:
function parseStuff(str) {
return JSON.parse(
str
.substring(1, (str.length - 1))
.replace(/'/g, '"')
);
}
但问题是,传递给控制器/容器的是什么(我的Rails知识有限,所以我继续我可以阅读的内容)。但是例如一些代码看起来像:
<instance of container/controller>.data('tableValues')
其中&#39; tableValues被定义为代码中较早的选择器,容器/控制器的实例可能是表对象本身我假设:
tableValues: 'table[data-table-options]' //A bunch more of these selectors are defined
所以基本上我试图设置一个HTML夹具我可以测试这个。我发布的HTML是它在chrome dev工具中的显示方式(显然在table元素中有很多东西,但我特别关注这个选择器)
答案 0 :(得分:3)
您将该属性称为table[data-table-values]
,这在两个帐户中不正确:
table[]
没有必要。我不确定你为什么要用它。这不是选择器,这是属性查找。data-table-values
应为table-values
。您的HTML属性称为“data-table-values”,但.data()
查找不需要任何HTML data- *属性。 这两个方法的最终结果是在底部的示例中有.data('table-values')
。
如果您想查找实际属性值,则需要包含data-
前缀,因为您正在搜索该特定HTML属性;例如,$test.attr('data-table-values')
,但对于data- *属性执行此操作是违反常规做法的。
关于.data()
方法应注意的一点是,它在内存中运行。它不会更新您的HTML。如果你使用任何类型的检查器,你会看到设置$test.data('foo','bar')
,它没有将foo
属性绑定到元素,也没有修改DOM,它在内部管理jQuery的值。
要将值用作JSON,您需要将其存储为格式良好的JSON,此时您正在使用单引号作为封装JSON字符串分隔符'{'':[]}'
,并且还要分隔对象键。您必须使用双引号来表示有效的JSON。
在下面的示例中,我修剪了前导和结束单引号('
),然后用双引号"
替换键周围的所有单引号。为清楚起见,我把它分成了几行,但可以浓缩成几行。
注意: 如果JSON有效且正确存储在data-*
属性中,那么客户端就不需要这么做工作清理它,代码会更简单
var $test = $('#test');
var str = $test.data('table-values'); // <=== was:"table[data-table-values]"
console.log('data-* value:', str);
// format to a valid JSON string
str = str.replace(/^'+/, ''); // remove leading single quote
str = str.replace(/'+$/, ''); // remove ending single quote
str = str.replace(/'/g, '"'); // use double quotes
console.log('Replaced single quotes:', str);
// make JS object
var obj = JSON.parse(str);
console.log('obj:', obj);
console.log('obj.header[1]:', obj.header[1]);
// make JSON string
console.log('JSON:', JSON.stringify(obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="test" data-table-values="'{'header': ['value1', 'value2']}'"></table>
以下是每个@guest271314建议的示例,该示例演示了HTML中格式正确的JSON。
请注意,行数要少得多(只有一行需要获取JSON对象)。提供了jQuery和ES6等价物:
// jQuery
var obj = $('#test').data('table-values');
console.log('obj:', obj);
console.log('obj.header[1]:', obj.header[1]);
console.log('JSON.stringify(obj):', JSON.stringify(obj));
// ES6
var obj2 = JSON.parse(document.querySelector('#test').dataset['tableValues']);
console.log('obj2:', obj2);
console.log('obj2.header[1]:', obj2.header[1]);
console.log('JSON.stringify(obj2):', JSON.stringify(obj2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="test" data-table-values='{"header": ["value1", "value2"]}'></table>
答案 1 :(得分:2)
问题是因为您需要向data-
方法提供属性名称减去data()
前缀,而不是元素选择器。试试这个:
var $test = $('#test');
console.log($test.data('table-values'));
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="test" data-table-values="'{'header': ['value1', 'value2']}'"></table>
&#13;
另请注意,如果您将属性提供为HTML编码的JSON,那么jQuery会自动为您反序列化,以便您可以立即使用对象的属性:
var $test = $('#test');
var obj = $test.data('table-values')
console.log(obj);
console.log(obj.header[0]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="test" data-table-values="{"header": ["value1","value2"]}"></table>
&#13;