Dojo FilteringSelect仅触发OnChange事件一次
我在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 {
}
}
当我创建这些类型在过去的小部件嗯,我已经做了如下,它几乎和你的一样,但注意到在更改处理...
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 widgets和defining 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 ...
如果你没有得到第二个事件,它必须在某个地方迷路。我想知道变量作用域是否会影响事物,但我不需要改变它们的任何范围。我只是将主函数移动到模块的返回块中。
谢谢@Jez - 这是我最初尝试的,但它只在我第一次从下拉列表中选择一个值时才起作用。任何额外的时间没有发生。 – Brian 2013-02-08 22:08:46
我刚刚检查了这段代码与我自己的一些工作,它确实有效,也许你可以添加一些额外的代码,我会仔细看看。 – Jeremy 2013-02-08 22:11:36
我已经添加了我的其他javascript代码。一般来说,我对Dojo和Web开发还很陌生。我能够使它大致与JSFiddle一起工作,但我无法保存小提琴。我想知道是否有可能会干扰ArcGIS JavaScript API的其他内容? – Brian 2013-02-08 23:12:17
只要把不同id
像阵列上:
var stateStore = new Memory({
data: [
{name:"Alabama", id:"AL"},
{name:"Alaska", id:"AK"}
]
});
- 如果你的阵列没有
id
,onChange
事件将不触发 - 如果两个
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
嗨,布赖恩,哪个版本的dojo在这里被使用? – Jeremy 2013-02-08 23:36:26
@Jez - 根据ESRI ArcGIS Javascript API,它包含了dojo 1.8。 – Brian 2013-02-08 23:44:35