easyui的datagrid的使用記錄

datagrid是在 table的基礎上變化而來的, 而不是在div的基礎上來的。 從div來變成 datagrid,樣式的設置仍是是比較麻煩的。php

dg=datagrid 的標題 來源於 columns 屬性, 其內容 來源於 url屬性。 關鍵是, 必定要設置這樣的屬性, 才能給你顯示標題和內容, 不然即便你寫了 tr等都不會顯示css

dg的url 最後輸出的內容 必須是 json格式: 若是是php的, 則要用echo, 若是是 其餘文件,就要用 json數據html

最重要的是: dg的前端 和 後臺 服務器之間的 通訊 , 都是 經過 ajax的方式 來 實現的。 若是在 php中 有 sleep語句的話, 會看到 加載loading...等待的效果。 ajax提交動做 發生在 每次你在前臺 點擊 下一頁等按鈕的時候, 前臺須要在ajax提交的時候, 向後臺服務器 傳送數據; 後臺須要 返回 json格式的 數據 給 前臺。

並且ajax的方式好像都是 post方式。
好比: 分頁, 前端 須要 向 後臺 傳遞數據: 一個是page(當前頁碼,便是第幾頁?), 一個是 pageSize(一頁多少條數據)。 而後後臺post獲取到 頁碼和頁數, 在 mysql的查詢語句中 ,用 limit start rowsCount, 來規範限定 返回的數據。
並且, 後臺 除了返回 當前頁面須要的部分 rows數據外, 還要返回一個 total總頁數。
最後的 返回結果 要寫成 json格式的: 這種 類型: {"total": $total, "rows": .....}前端

dg的主要內容:

一個是加載 dg的內容, 並完成分頁;
二個是, 排序,能夠只作 初始化的時候 排序;
三是: 設置dg的樣式, 有striped, rowNumbers, singSelected爲true等等.mysql

只要是ajax服務器端有echo內容的, 即便在前端沒有處理、使用 這些數據的代碼,好比沒有什麼alert的, 也是能夠看到服務器返回的數據的, 使用firebug的 network的 param, 和response,就能夠查看,並且這個實際上是查看得很詳細很全面 的。

關於isset和 empty在 查詢按鈕使用時的區別?

isset是判斷 $_POST的某個 變量名 是否設置了的, 主要是 用來 判斷 按鈕 是否被 單擊了的, 主要是 防止 頁面刷新時 執行代碼;
而 !empty 是判斷 $_POST的變量名的值是否爲空, 主要是用來判斷搜索框中是否有輸入 內容的, 經常使用的判斷就是:
if(isset($_POST['name']) && !empty($_POST['name'])){...}ajax

php中變量的兩邊使用 大括號?

主要有三種情形:sql

  • 一是避免 變量 和變量後面的字符串 連在一塊兒 , 從而引發混淆和錯誤;
  • 二是 在 變量的外面兩邊 使用 大括號, 能夠在 單引號中 也能夠輸出變量的值, 避免使用 點號來鏈接 字符串的麻煩
  • 三是, 在 變量的名稱後 使用大括號, 好比 $str{5} 能夠輸出字符串中的 第n 個字符。經常使用來判斷字符串的長度:if(!isset($str{5})){...}

==============================================數據庫

寫代碼的一個重要方法, 不是從上到下挨着挨着的寫, 而是先寫結構, 像if...else這些結構, 而後寫簡單的分支,最後才寫重要的最複雜的分支

  • dg的 增刪改 編輯操做, 相似於百度網盤, 工具欄上 各類操做按鈕, 而後在一個 obj={...}的各類 成員變量和成員方法中 來實現這些功能.
  • show 和hide方法, 能夠同時針對多個 匹配的元素, 好比: 多個按鈕 能夠同時一次性的 show 或 hide: $('#btn1, #btn2'). show(); $('#btn1, #btn2'). hide();

關於datagrid的主要內容有:

  1. 就是dg的內容載入, 一般是經過js的方式, 而且要分頁;
  2. 就是對內容進行 排序, 通常實現初始化的時候排序就行了
  3. 是設置dg的內容的一些樣式, 好比: striped, rowNumbers, singleSelect(可是若是要增刪改的話, 一般還不能設爲單選擇), 列寬自適應等fitColmns. 在列寬自適應的時候, 要同時設置每一列的寬度爲100(這個100是百分比)
  4. 設置工具欄, 增刪改的按鈕, 以及 實現查找功能. 工具欄 仍是 使用 id#tb的方式. 查詢的時候, 可能有多個查詢條件, 使用 And. 還要注意在查詢/查找 /過濾的狀況下, 分頁功能仍然要是正確的和可用的
    要注意查詢/ (以及後面的 增刪改等操做) 的過程基本上 都是3步走 : 在obj對應的 方法函數中, 先調用 dg的 load方法, 向服務器 傳遞 查詢條件的 鍵值對; 而後服務器端 接受查詢條件,在數據庫中進行 處理, 並返回結果; 而後 再在客戶端 用 ajax 處理接收到的數據.
  5. 5/6/7章 是進行增刪改操做的: 第五章是進行增長操做的 前臺處理和數據準備和ajax提交; 第六章是進行刪除和修改前臺處理和數據準備等; 第七章是講 增刪改的後臺服務器操做的

而有些操做是, 共同的: 好比 開始編輯的操做是: beginEdit, 結束編輯的操做是: endEdit.json

==========================================bootstrap

dg的數據加載?

  1. columns屬性是 兩個中括號, 每一個對象的屬性能夠有: field, title, checkbox, sortable, width, 數據的對齊方式align/valign, 跨列/行 rowspan, colspan等
  2. 列的內容, 只能從 url屬性中 經過 ajax 遠程加載, 要注意的是, url的內容, 是一個 json格式的數組, 數組元素是 json格式的對象 . 若是是從數據庫取數據, 必須進行json 格式處理.即:
    [{"id": 1, "name": "foo"}, .....] 的形式. 若是 php返回的格式 不是這樣的, 將不會加載數據 進來.
    好比
public function  dgcontent(){
    $sort = I('post.sort');
    $order = I('post.order');
    $page = I('post.page');
    $pageSize = I('post.rows');
    $from = $pageSize*($page-1);

    $dg = M('dg');
    $total = $dg -> count();

    $result = $dg->field('id, dept, class, name')->order("$sort $order")->limit($from,$pageSize)->select();
    $json="";
    for($i=0, $j=count($result); $i<$j; $i++){
      $json .= json_encode($result[$i]).',';
    }

    $json ='{"total":'.$total.',"rows":['. substr($json, 0 , -1).']}';
    
    echo $json;
  }

==========================================

strip和stripe的區別?

  • strip [ strip] : 的意思, 名詞時表示: 條, 帶, 狹長地帶, 帶子, 布帶的意思, 動詞, 則是 '剝奪'; '分割成條帶"
  • stripe [straip] 的意思 , 是 各類 條紋! 好比 斑馬身上的條紋, 橫條紋, 豎條紋, 測試壓力的複雜條紋之類的.

MySQL按照字段的 漢字的拼音排序,怎麼和常規的想象不同啊?

按照漢字的拼音排序,用的比較可能是在人名的排序中,按照姓氏的拼音字母,從A到Z排序; 若是存儲姓名的字段採用的是GBK字符集,那就好辦了,由於GBK內碼編碼時自己就採用了拼音排序的方法(經常使用一級漢字3755個採用拼音排序,二級漢字就不是了,但考慮到人名等都是經常使用漢字,所以只是針對一級漢字能正確排序也夠用了)。 直接在查詢語句後面 添加 order by name asc; 查詢結果按照姓氏的升序排序; 若是存儲姓名的字段採用的是 utf8字符集,須要在排序的時候對字段進行轉碼;對於的代碼是 order by convert(name using gbk) asc; 一樣,查詢的結果也是按照姓氏的升序排序(因此, 若是存儲的是utf8字符集, 由於有一個轉碼的過程, 因此看到的排序和想象中的不同.

count(1) 是什麼意思?

count(1),其實就是計算一共有多少符合條件的行。
1並非表示第一個字段,而是表示一個固定值。
其實就能夠想成表中有這麼一個字段,這個字段就是固定值1,count(1),就是計算一共有多少個1.
同理,count(2),也能夠,獲得的值徹底同樣,count('x'),count('y')都是能夠的。同樣的理解方式。在你這個語句理均可以使用,返回的值徹底是同樣的。就是計數。
count(*),執行時會把星號翻譯成字段的具體名字,效果也是同樣的,不過多了一個翻譯的動做,比固定值的方式效率稍微低一些。

=====================================

到底用margin仍是用top?

主要仍是從 語義和你的用途上來區分,雖然都能實現相同的效果。

什麼時候應當使用margin: 
- 不須要在border外側添加空白時。 
- 空白處不須要背景(色)時。 
- 上下相連的兩個盒子之間的空白,須要相互抵消時。如15px + 20px的margin,將獲得20px的空白。 

什麼時候應當時用padding: 
-  須要在border內測添加空白時。 
-  空白處須要背景(色)時。 
-  上下相連的兩個盒子之間的空白,但願等於二者之和時。如15px + 20px的padding,將獲得35px的空白。 

::: margin是用來隔開元素與元素的間距;padding是用來隔開元素與內容的間隔。
margin用於佈局分開元素使元素與元素互不相干;「老死不相往來」 是兩家人

padding用於元素與內容之間的間隔,讓內容(文字)與(包裹)元素之間有一段「呼吸距離」。 是一家人

======================================

關於js字面對象的定義:

/*在js中定義變量,並非必須加var的! 並且, 不加var表示的是 "全局變量", 是頂級對象window的成員變量

  • 直接定義的對象字面變量, 不像用function定義的類, 能夠用var什麼的, {}內部只能是 key: val形式的鍵值對(無序)集合,因此, 即便是
    定義成員變量, 也只能用 var_name: some_value的形式來定義, 而不能用 分號語句的形式. 同時, 全部的鍵值對之間 要用 逗號隔開
    */
//這裏的obj沒有加var, 就是全局對象window的屬性

obj={
  rowEdit : undefined,
  search: function(){
  },
  add: function(){
  },
  update: function(){
  },
  remove: function(){
  },
  save:function(){
  },
};

js中的幾種 假值和 空值? (參考: https://blog.csdn.net/u012739535/article/details/17621247, https://www.cnblogs.com/yangzhx/p/4019073.html )

包括: undefined, '', 0, null, false. 這些都叫 假值或空值, 在 if判斷中都是假. 可是它們仍是有區別的:

  1. 它們的類型不一樣: typeof( var_name) 能夠知道: undefined 的類型是: undefined, 0 的類型是: number, '' 的類型是string, null的類型是: object, 也就是說 null是對象的空值; false是boolean類型的.
  2. 這些空值相互之間 用 == 判斷 , 的結果 是 : 0, false , ''', 三者之間是相等的: 即 0 == false == '' 的結果是true的. 能夠認爲這三個是 " 假值". 而 undefined==null , 能夠認爲它們是空值. 可是 undefined和 null 跟 數字相加的結果是不一樣的: 好比: 10+null =10, 10+undefined = NaN.
    全部的假值 用 == 和 空值 比較的 結果 都是 false.
    假值 , 有一個實際的對象, 因此 能夠用 .toString() 方法.
    而空值, 連對象都沒有, 因此 不能用 .toString 方法, 不然將拋出異常

  3. 再就是它們 強制類型轉換 : String(var_name) 後的結果不一樣: 轉換成 字符串的時候, 結果分別 跟它們的 "原型字面字符串". 這在字符串拼接 累加的時候要注意.
  4. undefined表示 無效對象, 當定義一個變量未被初始化時, 就是undefined, 而 null是已經被初始化 爲空對象. 可是全部的空值和假值 用 === 判斷 都是false.

js中(包括其餘任何 面向對象的語言) 都是同樣的, 若是 要在對象中, (即對象內部) , 引用對象的成員變量, 都應該 加上對象自己的引用this, 不然凡是不加this的變量, 都認爲是全局變量 而不是對象自己的成員變量, 這樣就會報引用錯誤! 固然, 若是是在對象的外部, 引用對象的成員, 就要用對象的類名了, 好比: obj.rowEdit.

obj={
  rowEdit : undefined,
  search: function(){
....

  add: function(){
    if(!this.rowEdit){   // 這裏要加this
      $('#save, #cancel').show();
      $('#box').datagrid('insertRow',{
    index: 0, 
    row: { }
      });

datagrid如何禁止編輯某一行, 某一列或某一個 單元格?

參考 : https://www.cnblogs.com/langhua/p/3672820.html

  1. 禁止行編輯: 先獲取到某一行, 而後根據條件, 不調用beginEdit方法, 直接返回, 其餘則調用 beginEdit方法
  2. 禁止某一列編輯, 要麼直接就不用設置 列的 editor屬性; 若是設置了editor屬性, 則調用 getColumnOption, 返回列的屬性op, 而後設置 op.editor={} 爲空
  3. 禁止某一個單元格編輯...

=================================================

dg中, tp中, 凡是從控制器傳遞到 模板的變量, 好比: $this ->foo = 'foo',

  1. 那麼在 模板中, {$foo}是能夠直接解析的! 根本就不須要 再在 {$foo} 的兩邊再 考慮什麼引號了, 不論是單引號, 仍是 雙引號都再也不須要了! 特別是再 href傳遞變量的時候 加上 引號等 反而會出錯. 好比: url: "{:U('xscontent')}"+'/?class={$class}', 就行了.
  2. 可是 , 若是是 在 alert 等 語句中, 要 使用 模板變量的話, 你就仍是須要 加上 引號了, 由於 直接解析模板變量後, 就是 一個 "字符序列", 不是 字符串! 而報錯!

dg的後臺是如何返回數據, 來填充前臺的記錄行的?

/*datagrid的返回結果, 來填充 前臺的 數據行,必須嚴格要求json格式, 並且json的格式和屬性名必須是: 
     *  "rows:": json_object_array, 即必須是rows, 後面的數據必須是數組, 每一個數組元素必須是json格式的對象
     * echo '{"total":"11","rows":[{"id":"100", "class":"A_class", "name":"the_Name", "account":"the_account"}]}';
     */

==============================================

一個很重要的注意問題: 在ajax中, 若是 url的目標地址, target是空的字符串時, 該次 ajax 將提交給 "當前頁面"! 從而也會獲得 ajax 成功success的 結果! 而事實上 這在不少應用場景下 是 不容許的. 因此 你要 判斷 一下 你的 ajax url 目標地址 是否爲空

好比: 在 dg的 onAfterEdit事件中, 就要判斷 url 是否爲空, 而後纔去調用 ajax.

onAfterEdit: function(rowIndex, rowData, changes){  
      var inserted = $('#box').datagrid('getChanges', 'inserted');
      var updated = $('#box').datagrid('getChanges', 'updated');
      var url=info='';
      if(inserted.length>0){
    url='{:U("add")}';
    info='新增';
      }
      if(updated.length>0){
    url='{:U("update")}';
    info='修改';
      }

/*
     這裏很重要 , 要判斷一下 url是否爲空, 不然 即便任意地 雙擊 一行記錄, 再去 雙擊另一行記錄, 即便沒有和數據庫進行 修改操做, 也會提示 ajax的success提示信息 , 然而這個時錯誤的! 
*/
      if(url!='' && info != ''){   
    $.ajax({
    type: 'post',
    url: url,
    data: {row: rowData,},
    beforeSend: function(){
      $('#box').datagrid('loading');
    },
    success: function(data){
      if(data !== false){
        $('#box').datagrid('loaded');
        $('#box').datagrid('load');
        $('#box').datagrid('unselectAll');
        $.messager.show({
          title: '消息',
          msg: '1個班級 '+ info +' 成功', 
          showType: 'slide',
          timeout: 3000
        });
        obj.rowEdit = undefined;
      }
    },
});

===================================================

如何禁用datagrid的某一行被 單擊選中或 被 雙擊選中? 參考: https://blog.csdn.net/Dzq_Boyka/article/details/78531217

主要思想是, 在 onClickRow 和 onDblClickRow 事件中 , 必須顯示的調用 $('#box').datagrid('unselectRow', rowIndex)方法, 不能只是 簡單地 返回 return.

  1. 要想使dg 在 新增的時候, 不能選擇行或 雙擊行 操做, 那麼 能夠設置一個 標識變量: isAdded , 當 每次 新增的時候, 都從新設置 isAdded = false, 而後, 判斷 onClickRow 和 onDblClickRow 事件中 的 isAdded是否 爲false, 或者 true

  2. 可是又要保證 初次載入 datagrid的時候, 若是不點擊 新增的時候, 要可以 選擇單行, 或 雙擊單行操做, 就要 初始化 obj的 isAdded 爲true.

obj={
  rowEdit : undefined,
  isAdded: true,  // 這裏是 關鍵! 
  add: function(){
    // 一旦增長的時候, 就要從新初始化isAdded爲false, 由於只要保存/取消一次後, isAdded就失效了
    this.isAdded=false;

....
}

    onDblClickRow: function(rowIndex, rowData){
       // 在新增記錄的時候, 禁止單擊選行 和 雙擊選行

      if(!obj.isAdded){
      $('#box').datagrid('unselectRow', rowIndex);
      return;
      }
     
      // 雙擊某一行的時候, 首先要關閉以前可能被修改的行
      if(obj.rowEdit != undefined){
    $('#box').datagrid('endEdit', obj.rowEdit);
    obj.rowEdit = undefined;
      }
  ............
    },
    onClickRow: function(rowIndex, rowData){
          if(!obj.isAdded){
      $('#box').datagrid('unselectRow', rowIndex);
      return;
      }
    },

=====================================================

分頁器: pagination的ajax事件? 參考: https://blog.csdn.net/H12KJGJ/article/details/53672096

  1. 分頁器的分頁list , 不是固定的, 也不是什麼 倍數, 你能夠任意的自由的 設置 任意數值:
pageList     類型array    用法: 用戶能改變頁面尺寸。pageList 屬性定義了能改爲多大的尺寸。
代碼實例:

    $('#pp').pagination({
        pageList: [10,20,50,100]
    });
  1. 分頁器中 的一個 頁面 由兩個 因素來決定: 一個是: pageSize( 每個頁面的最大尺寸), pageNumber(頁數), 因此 每一頁的第一條數據的索引值就是: pageSize*(pageNumber-1);
    這個就是用來 作 數據庫的limit的 依據的:
    所以 : onSelectPage 事件, 就是 當從新改變了pageSize , 從新選擇了 pageNumber後所獲得的頁面.

  2. 總共有4個 ajax事件: onSelectPage, onBeforeRefresh, onRefresh, onChangePageSize... 所以, 在dg中改變分頁尺寸的事件是 : onChangePageSize的回調函數中寫

===========================================

關於bootstrap中的 table中的單元格內容 水平居中和 垂直居中? 參考: https://blog.csdn.net/peng_hong_fu/article/details/70662979

  1. 水平居中是: 寫 text-center類, 而垂直居中, 則是 寫 stye的 vertical-align: middle
  2. 要注意的是: th的水平居中, 要寫在 th單元格內 , 不能寫在th的父元素 tr中; 普通的td的水平居中能夠寫在父元素 tr中
    而垂直居中 , 不能簡單的寫: tbody tr td的樣式, 而是要 寫 .table tbody tr td. 由於後者的 css優先級爲 10+1+1+1 =13, 而前者的css優先級是: 1+1+1=3. 因此 要 優先執行 後者的css. 然後者的css正是在 bootstrap中定義的, 默認爲top. 因此 你簡單的寫 tbody tr td是改變不了的, 要被 bs的所覆蓋, 要想在 style 標籤中 " 覆蓋" bs的默認設置的話, 須要寫 完整: .table tbody tr td
  3. 總之, 選擇符越詳細越具體, 它的css優先級 值就越大. 優先級 就越高

css的優先級? 參考 https://blog.csdn.net/amyleeYMY/article/details/63685330

由四位數字 組成:
!important =1000,
id的優先級=100,
類, 僞類, 屬性的優先級 =10,
元素, 僞元素的優先級=1
這些優先級, 無論層次, 只要有一個就 加上相應的 優先級 數值. 最後 算 總和.

可是要注意:

  1. 僞元素 只有四個, 即 :before, :after, : first-letter, :first-line , 主要是表示位置的
    僞類 有更多, 只要是表示 "狀態"的, 好比 :link, :active, :visited, :hover, :focus, :first-child 等

  2. 若是有多個 相互衝突的 css規則 同時做用在同一個 元素上, 則最終 起做用的是: 以 定義這些類樣式的前後順序爲準, 後定義的樣式 會 覆蓋 先前定義的樣式, 即 後定義的樣式 最終 將起做用. 而跟 該元素上 , 多個類樣式 書寫的前後順序無關.

easyui的消息框 是異步的, 如何理解?

  1. 異步, 表示 它是 "非模態的", 雖然有 "遮照" 樣式, 可是 它並不會阻止 該消息框 後續的代碼的執行. 相反, 在執行 消息框的 回調函數時, 主函數的 剩餘代碼 已經執行完畢了! 因此這就是 爲何主函數中 沒法獲取 回調函數的 返回值的緣由

  2. 那麼 要想實現 模態 框的 效果, 想要 某些代碼 在 點擊 "肯定" 後, 再執行, 就要把 這些代碼 放在 消息框的 回調函數中, 由於 回調函數 總數在 用戶 單擊 "肯定" 按鈕後 才執行.

相關文章
相關標籤/搜索