2013-02-08 156 views
2

我在dojo.Dialog中有dojo.form.FilteringSelect小部件,它是以編程方式創建的。我將一個onChange事件連接到FilteringSelect,按照預期,我第一次選擇和輸入FilteringSelect。任何後續的時間我選擇一些新的事件,onChange事件不會觸發。Dojo FilteringSelect僅觸發OnChange事件一次

我試過在爲new FilteringSelect語句提供參數時聲明onChange屬性。我試過使用dojo.connect。我試過mySelectDijit.on。所有都有相同的效果。

var select = new dijit.form.FilteringSelect({ 
    id : "fields-select-" + expNum, 
    store : store, 
    required : false, 
    intermediateChanges : true 
}, fieldinput); 

dojo.connect(select, 'onChange', LoadOperatorValue); 

如何得到onChange觸發事件,每次FilteringSelect變化?

UPDATE:

我已經添加了相關的代碼。此代碼基於ArcGIS Javascript API v3.3,其中包含Dojo。

dojo.require("dijit.Dialog"); 
dojo.require("dijit.form.FilteringSelect"); 
dojo.require("dojo.store.Memory"); 
dojo.require("dijit.form.MultiSelect"); 
dojo.require("dijit.form.TextBox"); 
dojo.require("dijit.form.Textarea"); 
dojo.require("dijit.form.NumberSpinner"); 
dojo.require("dijit.form.DateTextBox"); 

var expNum = 1; 
var queryDiv; 
var layer; 
var dialog; 

function CreateDialog(lyr) { 

    layer = lyr; 

    queryDiv = dojo.create("div", { 
     id : "queryDiv" 
    }); 

    var buttonInput = dojo.create("button", { 
     id : "button" 
    }, queryDiv); 

    var button = new dijit.form.Button({ 
     id : "addExpression", 
     label : "Add Expression", 
     onClick : function() { 
      BuildExpression(layer); 
     } 
    }, buttonInput); 

    BuildExpression(layer) 

    dialog = new dijit.Dialog({ 
     title : "Query: " + layer.layerObject.name, 
     content : queryDiv, 
     style : "width: 600px" 
    }); 

    dialog.show(); 
} 

function BuildExpression(layer) { 

    var expDiv = dojo.create("div", { 
     class : "expression", 
     id : "expression-" + expNum 
    }, queryDiv); 

    var filterDiv = dojo.create("div", { 
     class : "filter", 
     id : "filter-" + expNum 
    }, expDiv); 

    var fieldSpan = dojo.create("span", { 
     id : "field-" + expNum, 
     class : "field" 
    }, filterDiv); 

    var operatorSpan = dojo.create("span", { 
     id : "operator-" + expNum, 
     class : "operator" 
    }, filterDiv); 

    var valueSpan = dojo.create("span", { 
     id : "value-" + expNum, 
     class : "value" 
    }, filterDiv); 

    var removeSpan = dojo.create("span", { 
     id : "remove-" + expNum, 
     class : "remove" 
    }, filterDiv); 

    var removeInput = dojo.create("button", { 
     id : "button" 
    }, removeSpan); 

    var removeButton = new dijit.form.Button({ 
     id : "removeExpression" + expNum, 
     label : "Remove", 
     onClick : function() { 
      dojo.destroy(expDiv); 
     } 
    }, removeInput); 

    var fieldinput = dojo.create("input", { 
     id : "field-input-" + expNum 
    }, fieldSpan); 

    var fields = []; 
    dojo.forEach(layer.layerObject.fields, function(field, index) { 
     if (index < layer.layerObject.infoTemplate.info.fieldInfos.length && layer.layerObject.infoTemplate.info.fieldInfos[index].visible == true) { 
      field.operatorSpan = operatorSpan; 
      field.valueSpan = valueSpan; 
      fields.push({ 
       name : field.alias, 
       id : field 
      }); 
     } 
    }); 

    var store = new dojo.store.Memory({ 
     data : fields 
    }); 

    var select = new dijit.form.FilteringSelect({ 
     id : "fields-select-" + expNum, 
     store : store, 
     required : false, 
     intermediateChanges : true 
    }, fieldinput); 

    dojo.connect(select, 'onChange', LoadOperatorValue); 
    expNum++ 
} 

function LoadOperatorValue(field) { debugger; 
    dojo.empty(field.operatorSpan); 
    dojo.empty(field.valueSpan); 

    if ("domain" in field && "codedValues" in field.domain) { 

     field.operatorSpan.innerHTML = "IS"; 

     var sel = dojo.create("select", { 
      id : "multiselect-" + expNum 
     }, field.valueSpan); 

     dojo.forEach(field.domain.codedValues, function(cv, index) { 
      dojo.create("option", { 
       innerHTML : cv.name, 
       value : cv.code 
      }, sel); 
     }); 

     var multiselect = new dijit.form.MultiSelect({}, sel); 

    } else if (field.type == "esriFieldTypeString") { 

     var operatorInput = dojo.create("input", { 
      id : "operator-input" 
     }, field.operatorSpan); 

     var operators = [{ 
      name : "IS", 
      id : " = " 
     }, { 
      name : "IS NOT", 
      id : " <> " 
     }, { 
      name : "LIKE", 
      id : " LIKE " 
     }, { 
      name : "NOT LIKE", 
      id : " NOT LIKE " 
     }]; 

     var opStore = new dojo.store.Memory({ 
      data : operators 
     }); 

     var select = new dijit.form.FilteringSelect({ 
      id : "operator-select-" + expNum, 
      store : opStore, 
      required : false 
     }, operatorInput); 

     var valueInput = dojo.create("input", { 
      id : "value-input" 
     }, field.valueSpan); 

     if (field.length < 50) { 
      var textBox = new dijit.form.TextBox({ 
       id : "value-input-" + expNum 
      }, valueInput); 
     } else { 
      var textBox = new dijit.form.Textarea({ 
       id : "value-input-" + expNum 
      }, valueInput); 
     } 

    } else if (field.type == "esriFieldTypeDouble" || field.type == "esriFieldTypeSingle" || field.type == "esriFieldTypeInteger" || field.type == "esriFieldTypeSmallInteger") { 

     var operatorInput = dojo.create("input", { 
      id : "operator-input" 
     }, field.operatorSpan); 

     var operators = [{ 
      name : "=", 
      id : " = " 
     }, { 
      name : "!=", 
      id : " <> " 
     }, { 
      name : "<", 
      id : " < " 
     }, { 
      name : "<=", 
      id : " <= " 
     }, { 
      name : ">", 
      id : " > " 
     }, { 
      name : ">=", 
      id : " >= " 
     }]; 

     var opStore = new dojo.store.Memory({ 
      data : operators 
     }); 

     var select = new dijit.form.FilteringSelect({ 
      id : "operator-select-" + expNum, 
      store : opStore, 
      required : false 
     }, operatorInput); 

     var valueInput = dojo.create("input", { 
      id : "value-input" 
     }, field.valueSpan); 

     var constraints = {}; 

     if ("domain" in field && "range" in field.domain) { 
      constraints.min = field.domain.range.min; 
      constraints.max = field.domain.range.max; 
     } 

     if (field.type == "esriFieldTypeDouble" || field.type == "esriFieldTypeSingle") { 
      constraints.places = 2; 
     } 

     var numberSpinner = new dijit.form.NumberSpinner({ 
      id : "value-input-" + expNum 
     }, valueInput); 

    } else if (field.type == "esriFieldTypeDate") { 

     var operatorInput = dojo.create("input", { 
      id : "operator-input" 
     }, field.operatorSpan); 

     var operators = [{ 
      name : "IS", 
      id : " = " 
     }, { 
      name : "IS NOT", 
      id : " <> " 
     }, { 
      name : "Before", 
      id : " < " 
     }, { 
      name : "Before or IS", 
      id : " <= " 
     }, { 
      name : "After", 
      id : " > " 
     }, { 
      name : "After or IS", 
      id : " >= " 
     }]; 

     var opStore = new dojo.store.Memory({ 
      data : operators 
     }); 

     var select = new dijit.form.FilteringSelect({ 
      id : "operator-select-" + expNum, 
      store : opStore, 
      required : false 
     }, operatorInput); 

     var valueInput = dojo.create("input", { 
      id : "value-input" 
     }, field.valueSpan); 

     var dateTextBox = new dijit.form.DateTextBox({ 
      id : "value-input-" + expNum 
     }, valueInput); 

    } else { 

    } 
} 
+0

嗨,布賴恩,哪個版本的dojo在這裏被使用? – Jeremy 2013-02-08 23:36:26

+0

@Jez - 根據ESRI ArcGIS Javascript API,它包含了dojo 1.8。 – Brian 2013-02-08 23:44:35

回答

2

當我創建這些類型在過去的小部件嗯,我已經做了如下,它幾乎和你的一樣,但注意到在更改處理...

var select = new dijit.form.FilteringSelect({ 
    id : "fields-select-" + expNum, 
    store : store, 
    required : false, 
    onChange: function(value){ 
     //do something here 
    } 
}, fieldinput); 

更新:從重新閱讀你的文章,我可以看到你已經嘗試過這種方法,我只是想我會把它留在答案作爲參考,因爲它在過去爲我工作。

UPDATE

關於dojo 1.8,它可能是值得使用dojo's templated widgets幫助消除了很多程序在你的JavaScript創建的元素的考慮。還值得通過一些其他dojo教程,如getting selective with dijit,custom widgetsdefining modules教程,他們將真正幫助您充分利用dojo小部件。 「越來越有選擇性」有一個過濾選擇小部件。

很難說出爲什麼你的onChange事件只被調度一次。我真的可以說的是,你完全簡化了你剛剛過濾的選擇部件的所有內容,並確保你可以單獨捕獲onChange事件多次。然後開始整合其餘的代碼。

對不起,我不能給你任何確切的答案,我會繼續尋找。

UPDATE

好,我剛剛你的代碼,並得到它使用Dojo 1.8在測試環境中運行,我不得不剝離出層對象,用一個簡單的數組替換它,但它似乎工作好。我還使用define將代碼更改爲模塊(在modules tutorial中進行了解釋)。這裏是代碼...

define(["dijit/Dialog", 
     "dijit/form/FilteringSelect", 
     "dojo/store/Memory", 
     "dijit/form/MultiSelect", 
     "dijit/form/TextBox", 
     "dijit/form/Textarea", 
     "dijit/form/NumberSpinner", 
     "dijit/form/DateTextBox"], 

    function(){ 

     var expNum = 1; 
     var queryDiv; 
     var layer; 
     var dialog; 

     function BuildExpression(layer) { 

      var expDiv = dojo.create("div", { 
       class : "expression", 
       id : "expression-" + expNum 
      }, queryDiv); 

      var filterDiv = dojo.create("div", { 
       class : "filter", 
       id : "filter-" + expNum 
      }, expDiv); 

      var fieldSpan = dojo.create("span", { 
       id : "field-" + expNum, 
       class : "field" 
      }, filterDiv); 

      var operatorSpan = dojo.create("span", { 
       id : "operator-" + expNum, 
       class : "operator" 
      }, filterDiv); 

      var valueSpan = dojo.create("span", { 
       id : "value-" + expNum, 
       class : "value" 
      }, filterDiv); 

      var removeSpan = dojo.create("span", { 
       id : "remove-" + expNum, 
       class : "remove" 
      }, filterDiv); 

      var removeInput = dojo.create("button", { 
       id : "button" 
      }, removeSpan); 

      var removeButton = new dijit.form.Button({ 
       id : "removeExpression" + expNum, 
       label : "Remove", 
       onClick : function() { 
        dojo.destroy(expDiv); 
       } 
      }, removeInput); 

      var fieldinput = dojo.create("input", { 
       id : "field-input-" + expNum 
      }, fieldSpan); 

      var fields = [{"name":"value1", "id":"v1"}, {"name":"value2", "id":"v2"}]; 
      //dojo.forEach(layer.layerObject.fields, function(field, index) { 
      // if (index < layer.layerObject.infoTemplate.info.fieldInfos.length && layer.layerObject.infoTemplate.info.fieldInfos[index].visible == true) { 
      //  field.operatorSpan = operatorSpan; 
      //  field.valueSpan = valueSpan; 
      //  fields.push({ 
      //   name : field.alias, 
      //   id : field 
      //  }); 
      // } 
      // }); 

      var store = new dojo.store.Memory({ 
       data : fields 
      }); 

      var select = new dijit.form.FilteringSelect({ 
       id : "fields-select-" + expNum, 
       store : store, 
       required : false, 
       intermediateChanges : true 
      }, fieldinput); 

      dojo.connect(select, 'onChange', function(value){console.log(value)}); 
      expNum++ 
     } 

     function LoadOperatorValue(field) { debugger; 
      dojo.empty(field.operatorSpan); 
      dojo.empty(field.valueSpan); 

      if ("domain" in field && "codedValues" in field.domain) { 

       field.operatorSpan.innerHTML = "IS"; 

       var sel = dojo.create("select", { 
        id : "multiselect-" + expNum 
       }, field.valueSpan); 

       dojo.forEach(field.domain.codedValues, function(cv, index) { 
        dojo.create("option", { 
         innerHTML : cv.name, 
         value : cv.code 
        }, sel); 
       }); 

       var multiselect = new dijit.form.MultiSelect({}, sel); 

      } else if (field.type == "esriFieldTypeString") { 

       var operatorInput = dojo.create("input", { 
        id : "operator-input" 
       }, field.operatorSpan); 

       var operators = [{ 
        name : "IS", 
        id : " = " 
       }, { 
        name : "IS NOT", 
        id : " <> " 
       }, { 
        name : "LIKE", 
        id : " LIKE " 
       }, { 
        name : "NOT LIKE", 
        id : " NOT LIKE " 
       }]; 

       var opStore = new dojo.store.Memory({ 
        data : operators 
       }); 

       var select = new dijit.form.FilteringSelect({ 
        id : "operator-select-" + expNum, 
        store : opStore, 
        required : false 
       }, operatorInput); 

       var valueInput = dojo.create("input", { 
        id : "value-input" 
       }, field.valueSpan); 

       if (field.length < 50) { 
        var textBox = new dijit.form.TextBox({ 
         id : "value-input-" + expNum 
        }, valueInput); 
       } else { 
        var textBox = new dijit.form.Textarea({ 
         id : "value-input-" + expNum 
        }, valueInput); 
       } 

      } else if (field.type == "esriFieldTypeDouble" || field.type == "esriFieldTypeSingle" || field.type == "esriFieldTypeInteger" || field.type == "esriFieldTypeSmallInteger") { 

       var operatorInput = dojo.create("input", { 
        id : "operator-input" 
       }, field.operatorSpan); 

       var operators = [{ 
        name : "=", 
        id : " = " 
       }, { 
        name : "!=", 
        id : " <> " 
       }, { 
        name : "<", 
        id : " < " 
       }, { 
        name : "<=", 
        id : " <= " 
       }, { 
        name : ">", 
        id : " > " 
       }, { 
        name : ">=", 
        id : " >= " 
       }]; 

       var opStore = new dojo.store.Memory({ 
        data : operators 
       }); 

       var select = new dijit.form.FilteringSelect({ 
        id : "operator-select-" + expNum, 
        store : opStore, 
        required : false 
       }, operatorInput); 

       var valueInput = dojo.create("input", { 
        id : "value-input" 
       }, field.valueSpan); 

       var constraints = {}; 

       if ("domain" in field && "range" in field.domain) { 
        constraints.min = field.domain.range.min; 
        constraints.max = field.domain.range.max; 
       } 

       if (field.type == "esriFieldTypeDouble" || field.type == "esriFieldTypeSingle") { 
        constraints.places = 2; 
       } 

       var numberSpinner = new dijit.form.NumberSpinner({ 
        id : "value-input-" + expNum 
       }, valueInput); 

      } else if (field.type == "esriFieldTypeDate") { 

       var operatorInput = dojo.create("input", { 
        id : "operator-input" 
       }, field.operatorSpan); 

       var operators = [{ 
        name : "IS", 
        id : " = " 
       }, { 
        name : "IS NOT", 
        id : " <> " 
       }, { 
        name : "Before", 
        id : " < " 
       }, { 
        name : "Before or IS", 
        id : " <= " 
       }, { 
        name : "After", 
        id : " > " 
       }, { 
        name : "After or IS", 
        id : " >= " 
       }]; 

       var opStore = new dojo.store.Memory({ 
        data : operators 
       }); 

       var select = new dijit.form.FilteringSelect({ 
        id : "operator-select-" + expNum, 
        store : opStore, 
        required : false 
       }, operatorInput); 

       var valueInput = dojo.create("input", { 
        id : "value-input" 
       }, field.valueSpan); 

       var dateTextBox = new dijit.form.DateTextBox({ 
        id : "value-input-" + expNum 
       }, valueInput); 

      } else { 

      } 
     } 

     return { 
      CreateDialog: function(lyr) { 

       layer = lyr; 

       queryDiv = dojo.create("div", { 
        id : "queryDiv" 
       }); 

       var buttonInput = dojo.create("button", { 
        id : "button" 
       }, queryDiv); 

       var button = new dijit.form.Button({ 
        id : "addExpression", 
        label : "Add Expression", 
        onClick : function() { 
         BuildExpression(layer); 
        } 
       }, buttonInput); 

       BuildExpression(layer) 

       dialog = new dijit.Dialog({ 
        title : "Query: ",// + layer.layerObject.name, 
        content : queryDiv, 
        style : "width: 600px" 
       }); 

       dialog.show(); 
      } 
     } 
    } 
) 

然後,我通過要求模塊在一個簡單的html文件,並調用CreateDialog函數來測試它...

require(
    ["dojo/parser", 
    "tb/testModule", 
    "dojo/domReady!"], 

    function(parser, testModule){    
     parser.parse(); 
     //test module 
     testModule.CreateDialog({}); 
    } 
) 

注:包「TB/testModule」使用TB,因爲這就是我在我的dojo config設置的包名。

如果您開始在已篩選的選擇框中輸入內容,只要您在數組中的兩個值中的任何一個上獲得自動填寫,您應該會看到控制檯中記錄的等效值。

這裏是我所得到的屏幕截圖,你可以看到,我第一次登錄值1的ID,則值2的id ...

enter image description here

如果你沒有得到第二個事件,它必須在某個地方迷路。我想知道變量作用域是否會影響事物,但我不需要改變它們的任何範圍。我只是將主函數移動到模塊的返回塊中。

+0

謝謝@Jez - 這是我最初嘗試的,但它只在我第一次從下拉列表中選擇一個值時才起作用。任何額外的時間沒有發生。 – Brian 2013-02-08 22:08:46

+0

我剛剛檢查了這段代碼與我自己的一些工作,它確實有效,也許你可以添加一些額外的代碼,我會仔細看看。 – Jeremy 2013-02-08 22:11:36

+0

我已經添加了我的其他javascript代碼。一般來說,我對Dojo和Web開發還很陌生。我能夠使它大致與JSFiddle一起工作,但我無法保存小提琴。我想知道是否有可能會干擾ArcGIS JavaScript API的其他內容? – Brian 2013-02-08 23:12:17

0

只要把不同id像陣列上:

var stateStore = new Memory({ 
     data: [ 
      {name:"Alabama", id:"AL"}, 
      {name:"Alaska", id:"AK"} 
       ] 
}); 
  1. 如果你的陣列沒有idonChange事件將不觸發
  2. 如果兩個id相同,onChange事件的價值將第一次開火。

@布賴恩 如果你把對象的ID,如:

var stateStore = new Memory({ 
     data: [ 
      {name:"Alabama", id:{val:"dummy1"}, 
      {name:"Alaska", id:{val:"dummy2"} 
       ] 
}); 

即使兩個ID對象是彼此不同的,該事件將不會開火,第二次是因爲FilteringSelect不會檢查兩個ID爲:

{val:"dummy1"}=={val:"dummy2"} 

,但它會檢查作爲

"[object Object]"=="[object Object]" //both are same and no onChange event will be fired