Dojo FilteringSelect仅触发OnChange事件一次

时间:2013-02-08 21:18:01

标签: javascript javascript-events dojo dijit.form

我在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更改时,如何触发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 { } } 事件?

更新

我已添加相关代码。此代码基于ArcGIS Javascript API v3.3,其中包含Dojo。

{{1}}

2 个答案:

答案 0 :(得分:2)

当我在过去创建这些类型的小部件时,我已经按照以下方式完成了它,它几乎和你的一样,但是请注意更改处理程序......

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

如果您开始输入已过滤的选择框,只要您在阵列中的两个值中的任何一个上获得自动完成,您就会看到控制台中记录的等效值。

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

enter image description here

如果你没有参加第二项赛事,一定会在某个地方迷路。我想知道变量范围是否会影响事物,但我没有必要改变它们的任何范围。我只是将main函数移动到模块的返回块中。

答案 1 :(得分:0)

只需将不同的id放在数组上,如:

var stateStore = new Memory({
        data: [
            {name:"Alabama", id:"AL"},
            {name:"Alaska", id:"AK"}
              ]
});
  1. 如果您的数组中没有idonChange事件将无法启动
  2. 如果两个id的值相同,onChange事件将首次触发。
  3. @布赖恩 如果你把对象放在你的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