2

我有一个以编程方式创建的dojo.form.FilteringSelect小部件。dojo.Dialog我第onChange一次FilteringSelect选择并进入FilteringSelect. 以后每次我选择新的东西时,该onChange事件都不会触发。

onChange在为我的语句提供参数时,我尝试过声明该属性new FilteringSelect。我试过使用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

更新:

我已经添加了相关代码。此代码基于 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 {

    }
}
4

2 回答 2

2

好吧,当我过去创建这些类型的小部件时,我已经完成了如下操作,它与您的几乎相同,但请注意 on change 处理程序...

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

更新:通过重新阅读您的帖子,我可以看到您已经尝试过这种方法,我只是想我会把它留在答案中以供参考,因为它过去对我有用。

更新

关于dojo 1.8,可能值得考虑使用dojo 的模板化小部件来帮助删除 javascript 中的许多程序化创建的元素。还值得阅读其他一些 dojo 教程,例如使用 dijit 获得选择性自定义小部件定义模块教程,它们将真正帮助您充分利用 dojo 小部件。“变得有选择性”的有过滤选择小部件。

很难说出为什么你的 onChange 事件只被调度一次。我真正能说的就是让您完全简化只有过滤选择小部件的所有内容,并确保您可以多次单独捕获 onChange 事件。然后开始重新集成其余代码。

对不起,我不能给你任何确切的答案,我会继续寻找。

更新

好的,我刚刚获取了您的代码并使用 dojo 1.8 在测试环境中运行,我不得不剥离层对象,用一个简单的数组替换它,但它似乎工作正常。我还使用定义将代码更改为模块(在模块教程中进行了解释)。这是代码...

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中设置包名的方式。

如果您开始在过滤后的选择框中输入,一旦您对数组中的 2 个值中的任何一个自动完成,您应该会在控制台中看到记录的等效值。

这是我得到的屏幕截图,你可以看到我首先记录了 value1 的 id,然后是 value2 的 id...

在此处输入图像描述

如果你没有得到第二个事件,它一定是在某个地方迷路了。我想知道变量范围是否会影响某些事情,但我不必更改它们的任何范围。我只是将主函数移到模块的返回块中。

于 2013-02-08T22:00:17.680 回答
1

只需id在数组上放置不同的内容,例如:

var stateStore = new Memory({
        data: [
            {name:"Alabama", id:"AL"},
            {name:"Alaska", id:"AK"}
              ]
});
  1. 如果id您的阵列上没有,onChange则不会触发事件
  2. 如果两者的值id相同,onChange则事件将仅在第一次触发。

@Brian如果你把对象放在你的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
于 2013-06-26T10:13:32.787 回答