2013-10-25 119 views
1

我正在使用arcgis的Javascript Api 3.7(包括dojo 1.9.1),並且我一直在開發一個自定義的模板化dijit,它有兩個filteringSelect控件,第一個得到正確的瞳孔,並且當用戶從第一個項目中選擇一個項目並在該特定時刻設置其數據存儲時,我有第二個項目被填充。這第二個filteringSelect每次都會正確填充,但onchange事件會發生,因爲函數處理程序永遠不會被觸發,所以我需要在第二個FilterinSelect的onchange事件上做一些其他的工作人員。第二個dojo FilteringSelect控件onChange事件沒有被觸發

看起來有些東西與第二個filteringSelect(處理器上下文猜測的東西)搞砸了,但我還沒弄明白。我的dijit HTML模板的

我的兩個過濾控制模板聲明(部分:

   <tr> 
       <td> 
        Capa: 
       </td> 
       <td> 
        <input data-dojo-type="dijit.form.ComboBox" name="layerDijit" id="layerDijit" 
          data-dojo-props="autoComplete:true, required:true, searchAttr:'name', style:'width:100%;'" 
          data-dojo-attach-point="layerDijit" data-dojo-attach-event="change:_handleLayerSelected"/> 
       </td> 
      </tr> 
      <tr> 
       <td> 
        Campo: 
       </td> 
       <td> 
        <input data-dojo-type="dijit.form.FilteringSelect" name="fieldDijit" id="fieldDijit" 
          data-dojo-props="autoComplete:true, required:true, searchAttr:'name', style:'width:100%;'" 
          data-dojo-attach-point="fieldDijit" data-dojo-attach-event="change:_handleFieldSelected"/> 
       </td> 
      </tr> 

Dijit的JS腳本:

用於填充第一濾波選擇

postCreate: function() { 
     this.inherited(arguments); 

     .... 

     this.rootMapLayer = this.map.getLayer("ELAPAS"); 
     if (this.rootMapLayer.loaded){ 
      this.listLayers(this.rootMapLayer); 
     } 
     else{ 
      this.rootMapLayer.on("load", lang.hitch(this, this.listLayers)); 
     } 

     //enlace de eventos (tested this, and it doesn't work for the second filtering select either) 
     //this.fieldDijit.on('change', lang.hitch(this, this._handleFieldSelected)); 
     //this.layerDijit.on('change', lang.hitch(this, this._handleLayerSelected)); 
    }, 

listLayers: function() { 

     var layerInfos = []; 

     layerInfos = array.filter(this.rootMapLayer.layerInfos,function(info,index){ 
      return info.subLayerIds === null; 
     }); 

     if(layerInfos.length === 0) { 
      console.error("No se encontro ninguna capa para el servicio de mapa seleccionado"); 
      return; 
     } 

     var layersStore = new Memory({ 
      data: layerInfos 
     }); 

     this.layerDijit.set('store', layersStore); 
    }, 

代碼代碼它處理名爲layerDijit的第一個filteringSelect中的選擇更改並加載第二個(FieldDijit)的數據:

_handleLayerSelected: function() { 
     var selectedLayer = this.layerDijit.item; 

     if(this.getSelectedLayerUrl() === null) { 
      return; 
     } 

     //Se limpia el campo actual 
     this.fieldDijit.set("value", ""); 

     //Se arma la url del layer específico para traer la información de la capa (sus campos) 
     var layerUrl = this.rootMapLayer.url + "/" + selectedLayer.id; 

     esri.request({ 
      url: layerUrl, 
      content: { 
       f: "json" 
      }, 
      handleAs: "json", 
      callbackParamName: 'callback', 
      load: lang.hitch(this, '_handleLayerInfo'), 
      error: lang.hitch(this, '_handleLayerInfoError') 
     }); 
    }, 
_handleLayerInfo: function(data) { 
     var layerInfo = data; 
     if (!layerInfo.fields) { 
      console.error("No se pudo obtener la información de los campos de la capa"); 
      return; 
     } 

     var fieldsStore = new Memory({ 
      data: layerInfo.fields 
     }); 

     this.fieldDijit.set('store', fieldsStore); 
    }, 

    getSelectedLayerUrl: function(){ 
     var selectedLayer = this.layerDijit.item; 
     if(!selectedLayer) { 
      return null; 
     } 
     //Se arma la url del layer específico para traer la información de la capa (sus campos) 
     return this.rootMapLayer.url + "/" + selectedLayer.id; 
    }, 

    _handleLayerInfoError: function(err){ 
     console.error(err); 
    }, 

不被解僱的功能,即supossed處理第二濾波的SE改變事件中選擇一個:

_handleFieldSelected: function() { 
     alert("doesn't get fired"); 
     /*var selectedField = this.fieldDijit.item; 

     if(!selectedField) { 
      return; 
     } */ 
    }, 

可不可以給我這個問題的一些建議?什麼我做錯了嗎?

在此先感謝

回答

3

bishop,感謝您的回答,我想我不清楚我的問題,我明白,當用戶(或背景中的某個東西)更改所選項目時,「onChange」事件應該被解僱在FilteringSelect中,所以我的問題是,當用戶從第二個FilteringSelect控件中選擇一個項目時,它的onchange事件沒有被觸發。

正如你建議我tryed一個簡單的例子(用硬編碼的內存對象)和它的工作,所以我就開始挖一點點,並意識到問題出在我的記憶對象,

Aparently在聲明內存對象,你必須確保有在下面的例子中數組集合對象提交的,像一個ID:

var stateStore = new Memory({ 
      data: [ 
       {name:"Alabama" id:"AL"}, 
       {name:"Alaska", id:"AK"}, 
       {name:"American Samoa", id:"AS"}, 
       {name:"Arizona", id:"AZ"}, 
       {name:"Arkansas", id:"AR"}, 
       {name:"Armed Forces Europe", id:"AE"}, 
       {name:"Armed Forces Pacific", id:"AP"}, 
       {name:"Armed Forces the Americas", id:"AA"}, 
       {name:"California", id:"CA"}, 
       {name:"Colorado", id:"CO"}, 
       {name:"Connecticut", id:"CT"}, 
       {name:"Delaware", id:"DE"} 
      ] 
     }); 
     this.fieldDijit.set('store', stateStore); 

當你沒有明確告訴它在內存中的對象的聲明,現在有一個叫做「id」的字段。就我而言,我assing在第二FilteringSelect來的內存對象數組沒有一個領域所謂的「ID」

,所以我改變:

var fieldsStore = new Memory({ 
      data: layerInfo.fields 
     }); 

爲:

var fieldsStore = new Memory({ 
      idProperty: "name", //added this 
      data: layerInfo.fields 
     }); 

,現在當第二個篩選器選擇中的選定項目發生更改時,事件將被觸發。

+0

是的,idProperty肯定需要在那裏。那個人以前至少咬過兩次!很高興你找到了源。 – bishop

1

基於我在讀什麼,我想你期待這樣的代碼:

this.fieldDijit.set('store', fieldsStore); 

使第二選擇你co-dependent select安排解僱其變化的事件 - - 畢竟,選擇已經「改變」,因爲它有不同的商店。

但這不是變化事件的含義。更改事件表示用戶已更改所選值。因此,在設置新商店之後,如果您在第二個下拉列表中選擇一個值,那麼您的更改處理程序應該會觸發。

下面是一個例子,我認爲它將你的簡化爲最簡單的元素。請注意,當您選擇第一個框的值時,第二個存儲區會更改,但其onchange事件不會觸發(如預期的那樣)。但是,當你選擇第二個框的值,將其平變化會觸發(如預期):

<!DOCTYPE html> 
<html> 
    <head> 
     <link href='//ajax.googleapis.com/ajax/libs/dojo/1.9.1/dijit/themes/claro/claro.css' rel='stylesheet' type='text/css' /> 
     <script src='//ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js'></script> 
    </head> 
    <body class='claro'> 
     <div data-dojo-id='s1' data-dojo-type='dojo/store/Memory' data-dojo-props='data:[{id:1,name:"A"}]'></div> 
     <div data-dojo-id='s2' data-dojo-type='dojo/store/Memory' data-dojo-props='data:[{id:1,name:"C"}]'></div> 
     <select data-dojo-id='first' data-dojo-type='dijit/form/ComboBox' data-dojo-props='store:s1'> 
      <script type='dojo/method' event='onChange'> 
       second.set('store', s2); 
      </script> 
     </select> 

     <select data-dojo-id='second' data-dojo-type='dijit/form/ComboBox'> 
      <script type='dojo/method' event='onChange'> 
       alert('I am changed'); 
      </script> 
     </select> 

     <script type='text/javascript'> 
     require(['dojo/ready', 'dojo/parser'], function (ready, Parser) { 
      ready(function() { 
       Parser.parse().then(function() { 
       }); 
      }); 
     }); 
     </script> 
    </body> 
</html> 

如果我不理解您所描述的錯誤,你可以發送一個簡單的測試案例?