Jquery data()在CSS选择器上返回undefined

时间:2017-03-22 21:47:52

标签: javascript jquery

我正在测试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;
&#13;
&#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元素中有很多东西,但我特别关注这个选择器)

2 个答案:

答案 0 :(得分:3)

检索数据 - *值

您将该属性称为table[data-table-values],这在两个帐户中不正确:

  1. table[]没有必要。我不确定你为什么要用它。这不是选择器,这是属性查找。
  2. data-table-values应为table-values。您的HTML属性称为“data-table-values”,但.data()查找不需要任何HTML data- *属性。
  3. 这两个方法的最终结果是在底部的示例中有.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。

    在下面的示例中,我修剪了前导和结束单引号('),然后用双引号"替换键周围的所有单引号。为清楚起见,我把它分成了几行,但可以浓缩成几行。

    注意: 如果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>

    更好的HTML

    以下是每个@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()前缀,而不是元素选择器。试试这个:

&#13;
&#13;
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;
&#13;
&#13;

另请注意,如果您将属性提供为HTML编码的JSON,那么jQuery会自动为您反序列化,以便您可以立即使用对象的属性:

&#13;
&#13;
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="{&quot;header&quot;: [&quot;value1&quot;,&quot;value2&quot;]}"></table>
&#13;
&#13;
&#13;