2017-08-10 136 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;”部分。对于

相关问题