ata-* 全局屬性 是一類被稱為自定義數(shù)據(jù)屬性的屬性,它賦予我們在所有 HTML 元素上嵌入自定義數(shù)據(jù)屬性的能力,并可以通過腳本(一般指JavaScript) 與 HTML 之間進(jìn)行專有數(shù)據(jù)的交換。
簡單的說就是html元素可以通過data-*屬性存一些數(shù)據(jù),類似于一個(gè)map,如果我們想在html的元素上額外的存一些東西是非常方便的。
一:讀取是沒問題的
比如我們讀取div中data-num的數(shù)據(jù):
<div id="div1" data-num="1">
dataSet
</div>
分別用jquery和js的方法讀取,結(jié)果都是1。
二:修改就有坑了
但是修改的data-num的時(shí)候就有意思了:
jquery設(shè)置data-num中的值為2
jquery讀取值的值是2
js讀取值的值是1,奇怪,查看下html元素
data-num的值還是1。。。
這個(gè)坑,坑了我一早上,后來百度下才知道,原來jquery設(shè)置的值是在緩存里。。。
果斷查看下jquery的源碼,真相都在代碼里:
三:正確的使用方式
如果需要修改dom元素上的data必須用js的方式:
document.getElementById("div1").dataset.num = "3"
四:結(jié)論
jquery用緩存的方式,無疑是為了提高讀寫的效率,但是緩存是個(gè)雙刃劍,方便我們使用的同時(shí)往往還是帶來困擾。建議對data的操作要統(tǒng)一,都用jquery或者都用js方式,不要混著用,如果要改變dom上元素的值那只能用js的方式。
PS:類似緩存的坑還有java中的Integer類,Integer中的-128到127的值是存在緩存中的
所以兩個(gè)Integer的值相互比較的時(shí)候,如果值在-128和127之間,兩個(gè)數(shù)相同,用 == 號會(huì)返回true,在-128和127范圍之外會(huì)返回false,給人造成額外的困擾,切記在java中Integer的比較一定要用equals()方法。
譯自: https://opensource.com/article/18/9/using-grails-jquery-and-datatables
作者: Chris Hermansen
譯者: jrg
本文介紹如何構(gòu)建一個(gè)基于 Grails 的數(shù)據(jù)瀏覽器來可視化復(fù)雜的表格數(shù)據(jù)。
我是 Grails 的忠實(shí)粉絲。當(dāng)然,我主要是熱衷于利用命令行工具來探索和分析數(shù)據(jù)的數(shù)據(jù)從業(yè)人員。數(shù)據(jù)從業(yè)人員經(jīng)常需要查看數(shù)據(jù),這也意味著他們通常擁有優(yōu)秀的數(shù)據(jù)瀏覽器。利用 Grails、 jQuery ,以及 DataTables jQuery 插件 ,我們可以制作出非常友好的表格數(shù)據(jù)瀏覽器。
DataTables 網(wǎng)站 提供了許多“食譜式”的教程文檔,展示了如何組合一些優(yōu)秀的示例應(yīng)用程序,這些程序包含了完成一些非常漂亮的東西所必要的 JavaScript、HTML,以及偶爾出現(xiàn)的 PHP 。但對于那些寧愿使用 Grails 作為后端的人來說,有必要進(jìn)行一些說明示教。此外,樣本程序中使用的數(shù)據(jù)是一個(gè)虛構(gòu)公司的員工的單個(gè)平面表格數(shù)據(jù),因此處理這些復(fù)雜的表關(guān)系可以作為讀者的一個(gè)練習(xí)項(xiàng)目。
本文中,我們將創(chuàng)建具有略微復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和 DataTables 瀏覽器的 Grails 應(yīng)用程序。我們將介紹 Grails 標(biāo)準(zhǔn),它是 Groovy 式的 Java Hibernate 標(biāo)準(zhǔn)。我已將代碼托管在 GitHub 上方便大家訪問,因此本文主要是對代碼細(xì)節(jié)的解讀。
首先,你需要配置 Java、Groovy、Grails 的使用環(huán)境。對于 Grails,我傾向于使用終端窗口和 Vim ,本文也使用它們。為獲得現(xiàn)代的 Java 環(huán)境,建議下載并安裝 Linux 發(fā)行版提供的 Open Java Development Kit (OpenJDK)(應(yīng)該是 Java 8、9、10 或 11 之一,撰寫本文時(shí),我正在使用 Java 8)。從我的角度來看,獲取最新的 Groovy 和 Grails 的最佳方法是使用 SDKMAN! 。
從未嘗試過 Grails 的讀者可能需要做一些背景資料閱讀。作為初學(xué)者,推薦文章 創(chuàng)建你的第一個(gè) Grails 應(yīng)用程序 。
正如上文所提,我將本文中員工信息瀏覽器的源代碼托管在 GitHub 上。進(jìn)一步講,應(yīng)用程序 embrow 是在 Linux 終端中用如下命令構(gòu)建的:
cd Projects
grails create-app com.nuevaconsulting.embrow
域類和單元測試創(chuàng)建如下:
grails create-domain-class com.nuevaconsulting.embrow.Position
grails create-domain-class com.nuevaconsulting.embrow.Office
grails create-domain-class com.nuevaconsulting.embrow.Employeecd embrowgrails createdomaincom.grails createdomaincom.grails createdomaincom.
這種方式構(gòu)建的域類沒有屬性,因此必須按如下方式編輯它們:
Position 域類:
package com.nuevaconsulting.embrow
class Position {
String name
int starting
static constraints = {
name nullable: false, blank: false
starting nullable: false
}
}com.Stringint startingstatic constraintsnullableblankstarting nullable
Office 域類:
package com.nuevaconsulting.embrow
class Office {
String name
String address
String city
String country
static constraints = {
name nullable: false, blank: false
address nullable: false, blank: false
city nullable: false, blank: false
country nullable: false, blank: false
}
}
Enployee 域類:
package com.nuevaconsulting.embrow
class Employee {
String surname
String givenNames
Position position
Office office
int extension
Date hired
int salary
static constraints = {
surname nullable: false, blank: false
givenNames nullable: false, blank: false
: false
office nullable: false
extension nullable: false
hired nullable: false
salary nullable: false
}
}
請注意,雖然 Position 和 Office 域類使用了預(yù)定義的 Groovy 類型 String 以及 int,但 Employee 域類定義了 Position 和 Office 字段(以及預(yù)定義的 Date)。這會(huì)導(dǎo)致創(chuàng)建數(shù)據(jù)庫表,其中存儲(chǔ)的 Employee 實(shí)例中包含了指向存儲(chǔ) Position 和 Office 實(shí)例表的引用或者外鍵。
現(xiàn)在你可以生成控制器,視圖,以及其他各種測試組件:
-all com.nuevaconsulting.embrow.Position
grails generate-all com.nuevaconsulting.embrow.Office
grails generate-all com.nuevaconsulting.embrow.Employeegrails generateall com.grails generateall com.grails generateall com.
此時(shí),你已經(jīng)準(zhǔn)備好了一個(gè)基本的增刪改查(CRUD)應(yīng)用程序。我在 grails-app/init/com/nuevaconsulting/BootStrap.groovy 中包含了一些基礎(chǔ)數(shù)據(jù)來填充表格。
如果你用如下命令來啟動(dòng)應(yīng)用程序:
grails run-app
在瀏覽器輸入 http://localhost:8080/,你將會(huì)看到如下界面:
Embrow 應(yīng)用程序主界面。
單擊 “OfficeController” 鏈接,會(huì)跳轉(zhuǎn)到如下界面:
Office 列表
注意,此表由 OfficeController 的 index 方式生成,并由視圖 office/index.gsp 顯示。
同樣,單擊 “EmployeeController” 鏈接 跳轉(zhuǎn)到如下界面:
employee 控制器
好吧,這很丑陋: Position 和 Office 鏈接是什么?
上面的命令 generate-all 生成的視圖創(chuàng)建了一個(gè)叫 index.gsp 的文件,它使用 Grails <f:table/> 標(biāo)簽,該標(biāo)簽?zāi)J(rèn)會(huì)顯示類名(com.nuevaconsulting.embrow.Position)和持久化示例標(biāo)識符(30)。這個(gè)操作可以自定義用來產(chǎn)生更好看的東西,并且自動(dòng)生成鏈接,自動(dòng)生成分頁以及自動(dòng)生成可排序列的一些非常簡潔直觀的東西。
但該員工信息瀏覽器功能也是有限的。例如,如果想查找 “position” 信息中包含 “dev” 的員工該怎么辦?如果要組合排序,以姓氏為主排序關(guān)鍵字,“office” 為輔助排序關(guān)鍵字,該怎么辦?或者,你需要將已排序的數(shù)據(jù)導(dǎo)出到電子表格或 PDF 文檔以便通過電子郵件發(fā)送給無法訪問瀏覽器的人,該怎么辦?
jQuery DataTables 插件提供了這些所需的功能。允許你創(chuàng)建一個(gè)完成的表格數(shù)據(jù)瀏覽器。
要基于 jQuery DataTables 創(chuàng)建員工信息瀏覽器,你必須先完成以下兩個(gè)任務(wù):
在目錄 embrow/grails-app/views/employee 中,首先復(fù)制 index.gsp 文件,重命名為 browser.gsp:
cd Projects
cd embrow/grails-app/views/employee
cp gsp browser.gsp
此刻,你自定義新的 browser.gsp 文件來添加相關(guān)的 jQuery DataTables 代碼。
通常,在可能的時(shí)候,我喜歡從內(nèi)容提供商處獲得 JavaScript 和 CSS;在下面這行后面:
<title><g:message code="default.list.label" args="[entityName]" /></title>
插入如下代碼:
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" >
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" >
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/scroller/1.4.4/js/dataTables.scroller.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.flash.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.html5.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/buttons/1.5.1/js/buttons.print.min.js "></script>
然后刪除 index.gsp 中提供數(shù)據(jù)分頁的代碼:
<div id="list-employee" class="content scaffold-list" role="main">
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<f:table collection="${employeeList}" />
<div class="pagination">
<g:paginate total="${employeeCount ?: 0}" />
</div>
</div>
并插入實(shí)現(xiàn) jQuery DataTables 的代碼。
要插入的第一部分是 HTML,它將創(chuàng)建瀏覽器的基本表格結(jié)構(gòu)。DataTables 與后端通信的應(yīng)用程序來說,它們只提供表格頁眉和頁腳;DataTables JavaScript 則負(fù)責(zé)表中內(nèi)容。
<div id="employee-browser" class="content" role="main">
<h1>Employee Browser</h1>
<table id="employee_dt" class="display compact" style="width:99%;">
<thead>
<tr>
<th>Surname</th>
<th>Given name(s)</th>
<th>Position</th>
<th>Office</th>
<th>Extension</th>
<th>Hired</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Surname</th>
<th>Given name(s)</th>
<th>Position</th>
<th>Office</th>
<th>Extension</th>
<th>Hired</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
</div>
接下來,插入一個(gè) JavaScript 塊,它主要提供三個(gè)功能:它設(shè)置頁腳中顯示的文本框的大小,以進(jìn)行列過濾,建立 DataTables 表模型,并創(chuàng)建一個(gè)處理程序來進(jìn)行列過濾。
<g:javascript>
$('#employee_dt tfoot th').each( function() {javascript
下面的代碼處理表格列底部的過濾器框的大小:
var title = $(this).text();
if (title == 'Extension' || title == 'Hired')
$(this).html('<input type="text" size="5" placeholder="' + title + '?" />');
else
$(this).html('<input type="text" size="15" placeholder="' + title + '?" />');
});titletitletitletitletitle
接下來,定義表模型。這是提供所有表選項(xiàng)的地方,包括界面的滾動(dòng),而不是分頁,根據(jù) DOM 字符串提供的裝飾,將數(shù)據(jù)導(dǎo)出為 CSV 和其他格式的能力,以及建立與服務(wù)器的 AJAX 連接。 請注意,使用 Groovy GString 調(diào)用 Grails createLink() 的方法創(chuàng)建 URL,在 EmployeeController 中指向 browserLister 操作。同樣有趣的是表格列的定義。此信息將發(fā)送到后端,后端查詢數(shù)據(jù)庫并返回相應(yīng)的記錄。
var table = $('#employee_dt').DataTable( {
"scrollY": 500,
"deferRender": true,
"scroller": true,
"dom": "Brtip",
"buttons": [ 'copy', 'csv', 'excel', 'pdf', 'print' ],
"processing": true,
"serverSide": true,
"ajax": {
"url": "${createLink(controller: 'employee', action: 'browserLister')}",
"type": "POST",
},
"columns": [
{ "data": "surname" },
{ "data": "givenNames" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extension" },
{ "data": "hired" },
{ "data": "salary" }
]
});
最后,監(jiān)視過濾器列以進(jìn)行更改,并使用它們來應(yīng)用過濾器。
table.columns().every(function() {
var that = this;
$('input', this.footer()).on('keyup change', function(e) {
if (that.search() != this.value && 8 < e.keyCode && e.keyCode < 32)
that.search(this.value).draw();
});
這就是 JavaScript,這樣就完成了對視圖代碼的更改。
});
</g:javascript>
以下是此視圖創(chuàng)建的UI的屏幕截圖:
這是另一個(gè)屏幕截圖,顯示了過濾和多列排序(尋找 “position” 包括字符 “dev” 的員工,先按 “office” 排序,然后按姓氏排序):
這是另一個(gè)屏幕截圖,顯示單擊 CSV 按鈕時(shí)會(huì)發(fā)生什么:
最后,這是一個(gè)截圖,顯示在 LibreOffice 中打開的 CSV 數(shù)據(jù):
好的,視圖部分看起來非常簡單;因此,控制器必須做所有繁重的工作,對吧? 讓我們來看看……
回想一下,我們看到過這個(gè)字符串:
"${createLink(controller: 'employee', action: 'browserLister')}"
對于從 DataTables 模型中調(diào)用 AJAX 的 URL,是在 Grails 服務(wù)器上動(dòng)態(tài)創(chuàng)建 HTML 鏈接,其 Grails 標(biāo)記背后通過調(diào)用 createLink() 的方法實(shí)現(xiàn)的。這會(huì)最終產(chǎn)生一個(gè)指向 EmployeeController 的鏈接,位于:
embrow/grails-app/controllers/com/nuevaconsulting/embrow/EmployeeController.groovy
特別是控制器方法 browserLister()。我在代碼中留了一些 print 語句,以便在運(yùn)行時(shí)能夠在終端看到中間結(jié)果。
def browserLister() {
// Applies filters and sorting to return a list of desired employees
首先,打印出傳遞給 browserLister() 的參數(shù)。我通常使用此代碼開始構(gòu)建控制器方法,以便我完全清楚我的控制器正在接收什么。
println "employee browserLister params $params"
println()
接下來,處理這些參數(shù)以使它們更加有用。首先,jQuery DataTables 參數(shù),一個(gè)名為 jqdtParams 的 Groovy 映射:
def jqdtParams = [:]
params.each { key, value ->
def keyFields = key.replace(']','').split(/\[/)
def table = jqdtParams
for (int f = 0; f < keyFields.size() - 1; f++) {
def keyField = keyFields[f]
if (!table.containsKey(keyField))
table[keyField] = [:]
table = table[keyField]
}
table[keyFields[-1]] = value
}
println "employee dataTableParams $jqdtParams"
println()
接下來,列數(shù)據(jù),一個(gè)名為 columnMap 的 Groovy 映射:
def columnMap = jqdtParams.columns.collectEntries { k, v ->
def whereTerm = null
switch (v.data) {
case 'extension':
case 'hired':
case 'salary':
if (v.search.value ==~ /\d+(,\d+)*/)
whereTerm = v.search.value.split(',').collect { it as Integer }
break
default:
if (v.search.value ==~ /[A-Za-z0-9 ]+/)
whereTerm = "%${v.search.value}%" as String
break
}
[(v.data): [where: whereTerm]]
}
println "employee columnMap $columnMap"
println()
接下來,從 columnMap 中檢索的所有列表,以及在視圖中應(yīng)如何排序這些列表,Groovy 列表分別稱為 allColumnList 和 orderList :
def allColumnList = columnMap.keySet() as List
println "employee allColumnList $allColumnList"
def orderList = jqdtParams.order.collect { k, v -> [allColumnList[v.column as Integer], v.dir] }
println "employee orderList $orderList"
我們將使用 Grails 的 Hibernate 標(biāo)準(zhǔn)實(shí)現(xiàn)來實(shí)際選擇要顯示的元素以及它們的排序和分頁。標(biāo)準(zhǔn)要求過濾器關(guān)閉;在大多數(shù)示例中,這是作為標(biāo)準(zhǔn)實(shí)例本身的創(chuàng)建的一部分給出的,但是在這里我們預(yù)先定義過濾器閉包。請注意,在這種情況下,“date hired” 過濾器的相對復(fù)雜的解釋被視為一年并應(yīng)用于建立日期范圍,并使用 createAlias 以允許我們進(jìn)入相關(guān)類別 Position 和 Office:
def filterer = {
createAlias 'position', 'p'
createAlias 'office', 'o'
if (columnMap.surname.where) ilike 'surname', columnMap.surname.where
if (columnMap.givenNames.where) ilike 'givenNames', columnMap.givenNames.where
if (columnMap.position.where) ilike 'p.name', columnMap.position.where
if (columnMap.office.where) ilike 'o.name', columnMap.office.where
if (columnMap.extension.where) inList 'extension', columnMap.extension.where
if (columnMap.salary.where) inList 'salary', columnMap.salary.where
if (columnMap.hired.where) {
if (columnMap.hired.where.size() > 1) {
or {
columnMap.hired.where.each {
between 'hired', Date.parse('yyyy/MM/dd',"${it}/01/01" as String),
Date.parse('yyyy/MM/dd',"${it}/12/31" as String)
}
}
} else {
between 'hired', Date.parse('yyyy/MM/dd',"${columnMap.hired.where[0]}/01/01" as String),
Date.parse('yyyy/MM/dd',"${columnMap.hired.where[0]}/12/31" as String)
}
}
}
是時(shí)候應(yīng)用上述內(nèi)容了。第一步是獲取分頁代碼所需的所有 Employee 實(shí)例的總數(shù):
def recordsTotal = Employee.count()
println "employee recordsTotal $recordsTotal"
接下來,將過濾器應(yīng)用于 Employee 實(shí)例以獲取過濾結(jié)果的計(jì)數(shù),該結(jié)果將始終小于或等于總數(shù)(同樣,這是針對分頁代碼):
def c = Employee.createCriteria()
def recordsFiltered = c.count {
filterer.delegate = delegate
filterer()
}
println "employee recordsFiltered $recordsFiltered"
獲得這兩個(gè)計(jì)數(shù)后,你還可以使用分頁和排序信息獲取實(shí)際過濾的實(shí)例。
def orderer = Employee.withCriteria {
filterer.delegate = delegate
filterer()
orderList.each { oi ->
switch (oi[0]) {
case 'surname': order 'surname', oi[1]; break
case 'givenNames': order 'givenNames', oi[1]; break
case 'position': order 'p.name', oi[1]; break
case 'office': order 'o.name', oi[1]; break
case 'extension': order 'extension', oi[1]; break
case 'hired': order 'hired', oi[1]; break
case 'salary': order 'salary', oi[1]; break
}
}
maxResults (jqdtParams.length as Integer)
firstResult (jqdtParams.start as Integer)
}
要完全清楚,JTable 中的分頁代碼管理三個(gè)計(jì)數(shù):數(shù)據(jù)集中的記錄總數(shù),應(yīng)用過濾器后得到的數(shù)字,以及要在頁面上顯示的數(shù)字(顯示是滾動(dòng)還是分頁)。 排序應(yīng)用于所有過濾的記錄,并且分頁應(yīng)用于那些過濾的記錄的塊以用于顯示目的。
接下來,處理命令返回的結(jié)果,在每行中創(chuàng)建指向 Employee、Position 和 Office 實(shí)例的鏈接,以便用戶可以單擊這些鏈接以獲取相關(guān)實(shí)例的所有詳細(xì)信息:
def dollarFormatter = new DecimalFormat('$##,###.##')
def employees = orderer.collect { employee ->
['surname': "<a href='${createLink(controller: 'employee', action: 'show', id: employee.id)}'>${employee.surname}</a>",
'givenNames': employee.givenNames,
'position': "<a href='${createLink(controller: 'position', action: 'show', id: employee.position?.id)}'>${employee.position?.name}</a>",
'office': "<a href='${createLink(controller: 'office', action: 'show', id: employee.office?.id)}'>${employee.office?.name}</a>",
'extension': employee.extension,
'hired': employee.hired.format('yyyy/MM/dd'),
'salary': dollarFormatter.format(employee.salary)]
}
最后,創(chuàng)建要返回的結(jié)果并將其作為 JSON 返回,這是 jQuery DataTables 所需要的。
def result = [draw: jqdtParams.draw, recordsTotal: recordsTotal, recordsFiltered: recordsFiltered, data: employees]
render(result as JSON)
}
大功告成。
如果你熟悉 Grails,這可能看起來比你原先想象的要多,但這里沒有火箭式的一步到位方法,只是很多分散的操作步驟。但是,如果你沒有太多接觸 Grails(或 Groovy),那么需要了解很多新東西 - 閉包,代理和構(gòu)建器等等。
在那種情況下,從哪里開始? 最好的地方是了解 Groovy 本身,尤其是 Groovy closures 和 Groovy delegates and builders 。然后再去閱讀上面關(guān)于 Grails 和 Hibernate 條件查詢的建議閱讀文章。
jQuery DataTables 為 Grails 制作了很棒的表格數(shù)據(jù)瀏覽器。對視圖進(jìn)行編碼并不是太棘手,但 DataTables 文檔中提供的 PHP 示例提供的功能僅到此位置。特別是,它們不是用 Grails 程序員編寫的,也不包含探索使用引用其他類(實(shí)質(zhì)上是查找表)的元素的更精細(xì)的細(xì)節(jié)。
我使用這種方法制作了幾個(gè)數(shù)據(jù)瀏覽器,允許用戶選擇要查看和累積記錄計(jì)數(shù)的列,或者只是瀏覽數(shù)據(jù)。即使在相對適度的 VPS 上的百萬行表中,性能也很好。
一個(gè)警告:我偶然發(fā)現(xiàn)了 Grails 中暴露的各種 Hibernate 標(biāo)準(zhǔn)機(jī)制的一些問題(請參閱我的其他 GitHub 代碼庫),因此需要謹(jǐn)慎和實(shí)驗(yàn)。如果所有其他方法都失敗了,另一種方法是動(dòng)態(tài)構(gòu)建 SQL 字符串并執(zhí)行它們。在撰寫本文時(shí),我更喜歡使用 Grails 標(biāo)準(zhǔn),除非我遇到雜亂的子查詢,但這可能只反映了我在 Hibernate 中對子查詢的相對缺乏經(jīng)驗(yàn)。
我希望 Grails 程序員發(fā)現(xiàn)本文的有趣性。請隨時(shí)在下面留下評論或建議。
via: https://opensource.com/article/18/9/using-grails-jquery-and-datatables
作者: Chris Hermansen 選題: lujun9972 譯者: jrg 校對: wxy
本文由 LCTT 原創(chuàng)編譯, Linux中國 榮譽(yù)推出
jq是一款輕量級的命令行json處理工具,可以幫助用戶輕松處理json格式的數(shù)據(jù)。它可以從標(biāo)準(zhǔn)輸入讀取json數(shù)據(jù),也可以從文件中讀取。同時(shí),它支持各種查詢和過濾操作,例如選擇、過濾、轉(zhuǎn)換、排序和格式化等。
jq是一種針對JSON格式數(shù)據(jù)處理的命令行工具,具有以下特點(diǎn):
yum install -y epel-release
[root@jeven ~]# yum search jq
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* epel: mirrors.tuna.tsinghua.edu.cn
====================================================== N/S matched: jq ======================================================
drupal7-jquery_update.noarch : Upgrades the version of jQuery in Drupal core to a newer version of jQuery
jq-devel.x86_64 : Development files for jq
js-jquery-mousewheel.noarch : A jQuery plugin that adds cross-browser mouse wheel support
js-jquery-ui.noarch : jQuery user interface
js-jquery-ui-touch-punch.noarch : Touch Event Support for jQuery UI
python-XStatic-JQuery-Migrate.noarch : JQuery-Migrate (XStatic packaging standard)
python-XStatic-JQuery-TableSorter.noarch : JQuery-TableSorter (XStatic packaging standard)
python-XStatic-JQuery-quicksearch.noarch : JQuery-quicksearch (XStatic packaging standard)
python-XStatic-jQuery.noarch : jQuery 1.10.2 (XStatic packaging standard)
python-XStatic-jquery-ui.noarch : jquery-ui (XStatic packaging standard)
python-tw2-jqplugins-flot.noarch : jQuery flot (plotting) for ToscaWidgets2
python-tw2-jqplugins-gritter.noarch : jQuery gritter (growl-like pop-ups) for ToscaWidgets2
python-tw2-jqplugins-jqplot.noarch : Toscawidgets2 wrapper for the jqPlot jQuery plugin
python-tw2-jqplugins-ui.noarch : jQuery UI for ToscaWidgets2
python-tw2-jquery.noarch : jQuery for ToscaWidgets2
jq.x86_64 : Command-line JSON processor
js-jquery.noarch : JavaScript DOM manipulation, event handling, and AJAX library
js-jquery1.noarch : JavaScript DOM manipulation, event handling, and AJAX library
nodejs-extend.noarch : Port of jQuery.extend for node.js and the browser
python-pyquery.noarch : A jQuery-like library for python
python2-XStatic-DataTables.noarch : DataTables jquery javascript framework (XStatic packaging standard)
xstatic-datatables-common.noarch : DataTables jquery javascript framework (XStatic packaging standard)
Name and summary matches only, use "search all" for everything.
yum -y install jq.x86_64
[root@docker yum.repos.d]# jq -V
jq-1.6
wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -O /usr/local/bin/jq
chmod +x /usr/local/bin/jq
使用jq --help查詢幫助信息
[root@jeven ~]# jq --help
jq - commandline JSON processor [version 1.6]
Usage: jq [options] <jq filter> [file...]
jq [options] --args <jq filter> [strings...]
jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.
The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).
For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq
Example:
$ echo '{"foo": 0}' | jq .
{
"foo": 0
}
Some of the options include:
-c compact instead of pretty-printed output;
-n use `null` as the single input value;
-e set the exit status code based on the output;
-s read (slurp) all inputs into an array; apply filter to it;
-r output raw strings, not JSON texts;
-R read raw strings, not JSON texts;
-C colorize JSON;
-M monochrome (don't colorize JSON);
-S sort keys of objects on output;
--tab use tabs for indentation;
--arg a v set variable $a to value <v>;
--argjson a v set variable $a to JSON value <v>;
--slurpfile a f set variable $a to an array of JSON texts read from <f>;
--rawfile a f set variable $a to a string consisting of the contents of <f>;
--args remaining arguments are string arguments, not files;
--jsonargs remaining arguments are JSON arguments, not files;
-- terminates argument processing;
Named arguments are also available as $ARGS.named[], while
positional arguments are available as $ARGS.positional[].
See the manpage for more options.
jq命令的選項(xiàng)解釋
-c 緊湊而不是漂亮的輸出;
-n 使用`null`作為單個(gè)輸入值;
-e 根據(jù)輸出設(shè)置退出狀態(tài)代碼;
-s 將所有輸入讀取(吸取)到數(shù)組中;應(yīng)用過濾器;
-r 輸出原始字符串,而不是JSON文本;
-R 讀取原始字符串,而不是JSON文本;
-C 為JSON著色;
-M 單色(不要為JSON著色);
-S 在輸出上排序?qū)ο蟮逆I;
--tab 使用制表符進(jìn)行縮進(jìn);
--arg a v 將變量$a設(shè)置為value<v>;
--argjson a v 將變量$a設(shè)置為JSON value<v>;
--slurpfile a f 將變量$a設(shè)置為從<f>讀取的JSON文本數(shù)組;
--rawfile a f 將變量$a設(shè)置為包含<f>內(nèi)容的字符串;
--args 其余參數(shù)是字符串參數(shù),而不是文件;
--jsonargs 其余的參數(shù)是JSON參數(shù),而不是文件;
-- 終止參數(shù)處理;
[root@jeven ~]# cat name.json
{
"name": "John",
"age": 30,
"city": "New York",
"hobbies": ["reading", "running", "traveling"],
"education": {
"degree": "Master's",
"major": "Computer Science",
"school": "University of California"
}
}
顯示json文件的所有的key
[root@jeven ~]# jq keys name.json
[
"age",
"city",
"education",
"hobbies",
"name"
]
[root@jeven ~]# jq .hobbies name.json
[
"reading",
"running",
"traveling"
]
[root@jeven ~]# jq .[] name.json
"John"
"30"
"New York"
[
"reading",
"running",
"traveling"
]
{
"degree": "Master's",
"major": "Computer Science",
"school": "University of California"
}
查詢json文件內(nèi)容
[root@jeven ~]# cat name.json |jq
{
"name": "John",
"age": 30,
"city": "New York",
"hobbies": [
"reading",
"running",
"traveling"
],
"education": {
"degree": "Master's",
"major": "Computer Science",
"school": "University of California"
}
}
計(jì)算name.json文件中值的長度
[root@jeven ~]# jq '.[] | length' name.json
4
2
8
3
3
[root@jeven ~]# echo '{ "jven": { "aa": { "bb": 123 } } }' | jq '.'
{
"jven": {
"aa": {
"bb": 123
}
}
}
在json文件中所有值中進(jìn)行過濾內(nèi)容。
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。