javascript - Dojo FilteringSelect 仅触发一次 OnChange 事件

标签 javascript dojo dom-events dijit.form

我在以编程方式创建的 dojo.Dialog 中有一个 dojo.form.FilteringSelect 小部件。我将 onChange 事件连接到 FilteringSelect,当我第一次选择并输入 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);

如何在每次 FilteringSelect 更改时触发 onChange 事件?

更新:

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

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

更新

关于dojo 1.8 ,可能值得考虑使用 dojo's templated widgets帮助删除 JavaScript 中大量以编程方式创建的元素。还值得浏览一些其他 dojo 教程,例如 getting selective with dijit , custom widgetsdefining modules教程,它们将真正帮助您充分利用 dojo 小部件。 “获得选择性”其中包含过滤选择小部件。

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

抱歉,我无法给您任何准确的答案,我会继续寻找。

更新

好的,我刚刚获取了您的代码并使用 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 中设置包名称的方式。 .

如果您开始在筛选的选择框中键入内容,一旦您在数组中的 2 个值中的任何一个上获得自动完成,您应该会看到控制台中记录的等效值。

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

enter image description here

如果您没有收到第二个事件,则它一定在某个地方丢失了。我想知道变量作用域是否会影响事物,但我不必更改它们的任何作用域。我刚刚将主函数移动到模块的返回 block 中。

关于javascript - Dojo FilteringSelect 仅触发一次 OnChange 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14781523/

相关文章:

javascript - 当事件在相同事件类型的处理程序中注册时,防止触发该事件

javascript - 我可以在 Firebase 上托管 Facebook 聊天机器人吗?

javascript - 顶部滚动条不可见

javascript - 如何将 dojo 工具提示放置在靠近文本的位置?

css - 使 Dojo 或 Ext JS4 小部件的外观和行为类似于 Kendo UI。要求会有多高?

javascript - 设置下载路径

javascript - 仅使用 HTML 将参数传递给 <a> href 标记内的链接

javascript - 在JavaScript中播放特定时间的音频

javascript - 使用 HTML JavaScript 属性 "onSOMETHING"或一次为所有元素在脚本上添加事件监听器?

jquery - 拖动子元素时触发父元素的“dragleave”