Dojo筛选Select仅激发OnChange事件一次

jpfvwuh4  于 2022-12-16  发布在  Dojo
关注(0)|答案(2)|浏览(165)

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

如何让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 {

    }
}
vbkedwbf

vbkedwbf1#

当我在过去创建这些类型的小部件时,我是这样做的,它几乎和你的一样,但是请注意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's templated widgets来帮助删除JavaScript中的大量编程创建元素,还可以参考其他一些Dojo教程,如getting selective with dijitcustom 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中就是这样设置包名的。*

如果您开始在筛选的选择框中键入内容,那么只要您在数组中的两个值中的任何一个上获得自动完成,您就应该在控制台中看到记录的等效值。
这是我得到的结果的屏幕截图,您可以看到我首先记录了value 1的id,然后记录了value 2的id...

如果你没有得到第二个事件,那它一定是在什么地方丢失了。我想知道变量作用域是否会影响一些事情,但是我没有改变任何作用域。我只是把main函数移到了模块的return块中。

ulmd4ohb

ulmd4ohb2#

只需在阵列上放置不同的id,如下所示:

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

1.如果阵列上没有id,则不会触发onChange事件
1.如果两个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

相关问题