2017-08-10 135 views
1

感謝這裏的一些幫助,我得到了Dojo dgrid的工作;甚至想出瞭如何將它與我的休息服務中的數據聯繫起來。dgrid(onDemandGrid)在第一次點擊按鈕時加載,但第二次點擊時出錯按鈕被點擊

現在我添加了一個輸入框,一個按鈕,所有的邏輯發生在按鈕單擊。但是,第二次點擊按鈕時,即使在輸入字段中有相同的輸入值,我也會得到一個錯誤。

錯誤:

類型錯誤:無法讀取性能在StoreMixin.js未定義的 '元素':33

包括圖片,所以你可以看到我的console.logs enter image description here

我讀到這How To reset the OnDemandGrid,但有必要檢查網格是否存在並執行不同的邏輯?我不能每次都「新」一個新的嗎?

CODE:

<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"CustomersGrid"'> 
    <label for="lastnameStartsWith">Lastname Starts With:</label> 
    <input id="lastnameStartsWith" type="text" name="lastnameStartsWith" value="Wag" 
      data-dojo-type="dijit/form/TextBox" 
      data-dojo-props="trim:true, propercase:true" /> 
    <br /> 
    <br /> 
     <button id="queryStudentsButton" data-dojo-type="dijit/form/Button" 
     data-dojo-type="dijit/form/Button" 
     data-dojo-props="iconClass:'dijitIconTask'"> 
      <span>Query</span> 
      <script type='dojo/on' data-dojo-event='click'> 
    require([ 
     'dstore/RequestMemory', 
     'dstore/Memory', 
     'dgrid/OnDemandGrid' 
    ], function (RequestMemory, Memory, OnDemandGrid) { 
        var url = '../students/' + dojo.byId('lastnameStartsWith').value; 
        console.log("query students for dataGrid latsnameStartsWith:" + dojo.byId('lastnameStartsWith').value);    

        require(['dojo/request'], function(request){ 
         request.get(url, 
          {headers: {"Content-Type": 'application/json', 
             "username": securityConfig.username, 
             "password": securityConfig.password}} 
           ) 
          .then(function(response){ 
           //console.log("string response=" + response); 
           var respJSON = JSON.parse(response); 
           var respDataForDGrid = respJSON.recordset; 
           console.log("got respJSON back, num rows= " + respDataForDGrid.length);  


           //================================================   
           // Create an instance of OnDemandGrid referencing the store 
           console.log("Debug1");    

           var grid2 = new OnDemandGrid({ 
            collection: new Memory({ data: respDataForDGrid }), 
            columns: { 
             student_id: 'ID', 
             student_firstname: 'First Name', 
             student_lastname: 'Last Name', 
             student_city: 'City', 
             student_state: 'State', 
             student_zip: 'Zip' 
            } 
           }, 'grid2');          

           console.log("Debug2");    

           grid2.startup(); 
           console.log("Debug3");    

          }, 
          function(error){ 
           console.log("Error=" + error); 
           //dom.byId('studentFeedback').value += response; 
          }); 
        }); 
    }); 
      </script> 
     </button> 
<h2>My demoGrid - From JSON RestService (Database)</h2> 
<div id='grid2'></div> 

</div> 

部分 -

enter image description here

我試過此頁面上的代碼和代碼的組合: How To reset the OnDemandGrid

if (grid2Registered){ 
    console.log("reuse existing grid"); 
    grid2Registered.set('collection', memStore); 
    // refresh: clear the grid and re-queries the store for data. 
    grid2Registered.refresh(); 
    } 
    else{...  

Doc here(https://github.com/SitePen/dgrid/blob/v0.4.3/doc/components/core-components/OnDemandList-and-OnDemandGrid.md)說:

Clears the grid and re-queries the store for data. If keepScrollPosition is true on either the instance or the options passed to refresh, an attempt will be made to preserve the current scroll position. OnDemandList returns a promise from refresh, which resolves when items in view finish rendering. The promise resolves with the QueryResults that were rendered.

+0

如果您已經創建了網格,那麼在您的結構/列保持不變的情況下使用新的商店刷新網格總是可取的(至少這是我所做的)。這樣,您可以避免每次查詢時創建網格的開銷。 –

+0

那麼你會如何實現呢?保持一個櫃檯?或者檢查如何檢查我的grid2是否先前已定義? – NealWalters

+1

如果您採用模板化方法,即在html中定義小部件,則可以使用data-dojo-attach-point來引用網格。如果採取編程方式,則可以爲網格分配一個id(請注意,對於每個dijit,id必須是唯一的),並將其引用爲dijit.byId('yourId')。 –

回答

2

這一個一直很難!下面是一個工作示例。

首先我從聲明式切換到編程式的onClick函數:聲明性腳本由dojo解析,因此你不能在調試器下檢查它們(設置斷點等)(至少我不知道怎麼做)。所以在我看來,好的做法是避免它們。

然後,實際上這個錯誤是由於使用相同的id重新實例化dgrid,所以您確實需要一種方法來檢測dgrid是否已經存在。但是有一個訣竅:對於dgrid需要被dijit系統正確處理,他們需要與dijitRegistry擴展混合在一起。有關詳細信息,請參閱here

然後,您可以使用registry.byId('grid2')來檢測dgrid已存在。我可以跳過respDataForDgrid部分,直接使用respJSON(可能是由於你的服務器端(?)的不同) - 我在服務器端使用了一個帶有json數組的簡單文本文件)。

<!DOCTYPE HTML><html lang="en"> 
<head> 
<meta charset="utf-8"> 
<title>Neal Walters stask overflow test</title> 
<link rel="stylesheet" 
    href="dojo-release-1.12.2-src/dijit/themes/claro/claro.css" 
    media="screen"> 
<link rel="stylesheet" 
    href="dojo-release-1.12.2-src/dgrid/css/dgrid.css" media="screen"> 

</head> 
<body class="claro"> 
    <div data-dojo-type="dijit/layout/ContentPane" 
     data-dojo-props='title:"CustomersGrid"'> 
     <label for="lastnameStartsWith">Lastname Starts With:</label> <input 
      id="lastnameStartsWith" type="text" name="lastnameStartsWith" 
      value="Wag" data-dojo-type="dijit/form/TextBox" 
      data-dojo-props="trim:true, propercase:true" /> <br /> <br /> 
     <button id="queryStudentsButton" data-dojo-type="dijit/form/Button" 
      data-dojo-props="iconClass:'dijitIconTask', onClick: myClick">Query</button> 
     <h2>My demoGrid - From JSON RestService (Database)</h2> 
     <div id='grid2'></div> 

    </div> 
    <script src="dojo-release-1.12.2-src/dojo/dojo.js" 
     data-dojo-config="async:true"></script> 
    <script type="text/javascript"> 
      require(["dojo", "dojo/parser", "dojo/domReady!"], 
      function(dojo, parser){ 
       parser.parse(); 
      }); 
     function myClick(){ 
     var url = 'students/' + dojo.byId('lastnameStartsWith').value, securityConfig = {username: 'john', password: 'Doe'}; 
        console.log("query students for dataGrid latsnameStartsWith:" + dojo.byId('lastnameStartsWith').value);    

        require(['dojo/_base/declare', 'dojo/request', "dijit/registry", "dstore/RequestMemory", "dstore/Memory", "dgrid/OnDemandGrid", "dgrid/extensions/DijitRegistry"], function(declare, request, registry, RequestMemory, Memory, OnDemandGrid, DijitRegistry){ 
         request.get(url,{}) 
          .then(function(response){ 
           console.log("string response=" + response); 
           var respJSON = JSON.parse(response); 
           //var respDataForDGrid = respJSON.recordset; 
           //console.log("got respJSON back, num rows= " + respDataForDGrid.length);  


           //================================================   
           // Create an instance of OnDemandGrid referencing the store 
           console.log("Debug1");    
           var theGrid = registry.byId('grid2'); 
           if (theGrid){ 
            theGrid.set('collection', new Memory({data: respJSON})); 
           }else{ 
            var grid2 = new (declare([OnDemandGrid, DijitRegistry]))({ 
             collection: new Memory({ data: respJSON }), 
             columns: { 
              student_id: 'ID', 
              student_firstname: 'First Name', 
              student_lastname: 'Last Name', 
              student_city: 'City', 
              student_state: 'State', 
              student_zip: 'Zip' 
             } 
            }, 'grid2');          

            console.log("Debug2");    

            grid2.startup(); 
            console.log("Debug3"); 
           }    

          }, 
          function(error){ 
           console.log("Error=" + error); 
           //dom.byId('studentFeedback').value += response; 
          }); 
        }); 
     }; 
      </script> 
</body> 
</html> 
+0

謝謝,我將繼續嘗試轉向編程代碼;我從一開始就混合了不同的樣本。這是一個很好的學習練習,但我可以看到它比我計劃的要花費更多的時間。我新來重構我的代碼,學習如何使用更多的小純函數。我已經開始嘗試在SELECT邏輯上取得一些成功(找出用戶點擊了哪一行)。你能看看我上面的「第二部分」嗎?原來的錯誤消失了,但新的行似乎覆蓋了舊的行(一次顯示兩個字母)。 – NealWalters

+0

我只發佈了代碼片段:如果在頂部:\t 所以不要以爲我需要你的parser.parse。 也有過這種接近頂部:\t <腳本類型= 「道場/要求」> \t \t DOM: 「道場/ DOM」,註冊表: 「的dijit /註冊表」 \t得到一個稍微的dijit /註冊表不同的方式 – NealWalters

+0

你確實需要保持parser.parse。有關解釋,請參閱https://dojotoolkit.org/documentation/tutorials/1.10/declarative/。您可以刪除「parseOnLoad:false;」部分。對於

相關問題