整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          jquery操作HTML data全局屬性緩存的坑

          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)用程序 。

          獲取員工信息瀏覽器應(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ù)瀏覽器。

          創(chuàng)建員工信息瀏覽器視圖和控制器的方法

          要基于 jQuery DataTables 創(chuàng)建員工信息瀏覽器,你必須先完成以下兩個(gè)任務(wù):

          1. 創(chuàng)建 Grails 視圖,其中包含啟用 DataTable 所需的 HTML 和 JavaScript
          2. 給 Grails 控制器增加一個(gè)方法來控制新視圖。

          員工信息瀏覽器視圖

          在目錄 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ù):



          好的,視圖部分看起來非常簡單;因此,控制器必須做所有繁重的工作,對吧? 讓我們來看看……

          控制器 browserLister 操作

          回想一下,我們看到過這個(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 條件查詢的建議閱讀文章。

          結(jié)語

          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ù)推出

          點(diǎn)擊“了解更多”可訪問文內(nèi)鏈接

          inux系統(tǒng)之jq工具的基本使用

          • 一、jq工具介紹
            • 1. jq工具簡介
            • 2. jq工具的特點(diǎn)
          • 二、jq工具的安裝
            • 1. yum安裝jq
            • 2. 二進(jìn)制安裝jq
          • 三、jq命令的使用幫助
            • 1. 查詢jq命令幫助信息
            • 2. jq命令的選項(xiàng)解釋
          • 四、jq命令的基本使用
            • 1. 顯示json文件的所有的key
            • 2. 顯示key對應(yīng)的值
            • 3. 查詢json文件
            • 4. 計(jì)算值的長度
            • 5. 輸出美觀的格式
            • 6. 過濾json文件中的鍵值

          一、jq工具介紹

          1. jq工具簡介

          jq是一款輕量級的命令行json處理工具,可以幫助用戶輕松處理json格式的數(shù)據(jù)。它可以從標(biāo)準(zhǔn)輸入讀取json數(shù)據(jù),也可以從文件中讀取。同時(shí),它支持各種查詢和過濾操作,例如選擇、過濾、轉(zhuǎn)換、排序和格式化等。

          2. jq工具的特點(diǎn)

          jq是一種針對JSON格式數(shù)據(jù)處理的命令行工具,具有以下特點(diǎn):

          • 快速和高效:jq使用C語言編寫,處理JSON數(shù)據(jù)非常快速和高效。
          • 靈活和強(qiáng)大:jq具有豐富的功能和靈活的語法,能夠處理復(fù)雜的JSON數(shù)據(jù)結(jié)構(gòu)和進(jìn)行高級的JSON數(shù)據(jù)操作。
          • 命令行工具:jq是一個(gè)命令行工具,可從終端中直接調(diào)用,方便快捷。
          • 跨平臺:jq可在多種操作系統(tǒng)(包括Unix/Linux、Windows和macOS)上使用。
          • 開源:jq是一個(gè)開源工具,用戶可自由修改和分發(fā)。
          • 支持管道:jq支持從一個(gè)命令輸出管道到另一個(gè)命令作為輸入,使得數(shù)據(jù)處理更加靈活和高效。

          二、jq工具的安裝

          1. yum安裝jq

          • 需要提前安裝epel源
          yum install -y epel-release
          
          • 搜索jq命令的軟件包
          [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.
          
          
          • 安裝jq工具
          yum -y install jq.x86_64
          
          • 查看jq版本
          [root@docker yum.repos.d]# jq -V
          jq-1.6
          
          

          2. 二進(jìn)制安裝jq

          • 下載jq工具的軟件包
          wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64  -O   /usr/local/bin/jq
          
          • 設(shè)置權(quán)限
          chmod +x /usr/local/bin/jq
          

          三、jq命令的使用幫助

          1. 查詢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.
          
          

          2. jq命令的選項(xiàng)解釋

          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ù)處理;
          
          

          四、jq命令的基本使用

          1. 顯示json文件的所有的key

          • 查看當(dāng)前測試name.json文件內(nèi)容
          [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"
          ]
          
          

          2. 顯示key對應(yīng)的值

          • 顯示某個(gè)key對應(yīng)的值
          [root@jeven ~]# jq .hobbies  name.json 
          [
            "reading",
            "running",
            "traveling"
          ]
          
          
          • 顯示所有key對應(yīng)的值
          [root@jeven ~]# jq .[] name.json 
          "John"
          "30"
          "New York"
          [
            "reading",
            "running",
            "traveling"
          ]
          {
            "degree": "Master's",
            "major": "Computer Science",
            "school": "University of California"
          }
          
          

          3. 查詢json文件

          查詢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"
            }
          }
          
          

          4. 計(jì)算值的長度

          計(jì)算name.json文件中值的長度

          [root@jeven ~]# jq '.[] | length' name.json 
          4
          2
          8
          3
          3
          
          

          5. 輸出美觀的格式

          [root@jeven ~]# echo '{ "jven": { "aa": { "bb": 123 } } }' | jq '.'
          {
            "jven": {
              "aa": {
                "bb": 123
              }
            }
          }
          

          6. 過濾json文件中的鍵值

          在json文件中所有值中進(jìn)行過濾內(nèi)容。


          主站蜘蛛池模板: 国产精品亚洲产品一区二区三区| 99精品一区二区三区| 奇米精品一区二区三区在线观看| 久久国产精品视频一区| 内射一区二区精品视频在线观看| 精品伦精品一区二区三区视频| 国产对白精品刺激一区二区| 岛国无码av不卡一区二区| 日韩视频一区二区在线观看| 久久无码人妻一区二区三区午夜| 国产一区二区精品久久岳√| 亚洲Av高清一区二区三区| 国模少妇一区二区三区| 中文字幕一区二区三区有限公司 | 亚洲无人区一区二区三区| 一区二区手机视频| 无码一区二区波多野结衣播放搜索| 国产日韩一区二区三区在线观看| 国产一区二区精品久久岳| 无码国产精品一区二区高潮| 国产高清一区二区三区视频| 肉色超薄丝袜脚交一区二区| 日韩制服国产精品一区| 国产成人高清精品一区二区三区| 一区二区在线播放视频| 国产成人高清亚洲一区久久| 亚洲综合av一区二区三区| 亚洲国产成人久久综合一区| 久久久精品人妻一区二区三区| 国产亚洲情侣一区二区无| 国产乱码精品一区二区三| 国产爆乳无码一区二区麻豆 | 亚洲一区中文字幕久久| 国产在线一区二区在线视频| 国产一区视频在线| 精品一区二区三区四区在线播放| 亚洲伦理一区二区| 91久久精品无码一区二区毛片| 亚洲乱码一区av春药高潮| 亚洲午夜一区二区电影院| 亚洲国产AV一区二区三区四区 |