第二个dojo FilteringSelect控件onChange事件不会被触发

时间:2013-10-25 15:49:21

标签: javascript select dojo esri dijit.form

我正在使用arcgis Javascript Api 3.7(包括dojo 1.9.1),我一直在开发一个自定义模板化dijit,它有两个filteringSelect控件,第一个被正确化瞳,我有第二个当用户从第一个在该特定时刻设置其数据存储的项目中选择一个项目时,将填充。每次都会正确填充第二个filteringSelect,但是onchange事件会发生一些事情,因为函数处理程序永远不会被触发,我需要在第二个FilterinSelect的onchange事件上做一些其他人员。

似乎有些东西搞砸了第二个filteringSelect(用处理程序上下文猜测一些东西),但我还是想不通。

我的两个过滤控件模板声明(我的dijit html模板的一部分:

                <tr>
                <td>
                    Capa:
                </td>
                <td>
                    <input data-dojo-type="dijit.form.ComboBox" name="layerDijit" id="layerDijit"
                           data-dojo-props="autoComplete:true, required:true, searchAttr:'name', style:'width:100%;'"
                           data-dojo-attach-point="layerDijit" data-dojo-attach-event="change:_handleLayerSelected"/>
                </td>
            </tr>
            <tr>
                <td>
                    Campo:
                </td>
                <td>
                    <input data-dojo-type="dijit.form.FilteringSelect" name="fieldDijit" id="fieldDijit"
                           data-dojo-props="autoComplete:true, required:true, searchAttr:'name', style:'width:100%;'"
                           data-dojo-attach-point="fieldDijit" data-dojo-attach-event="change:_handleFieldSelected"/>
                </td>
            </tr>

Dijit JS脚本:

填充第一个过滤选择

的代码
postCreate: function() {
        this.inherited(arguments);

        ....

        this.rootMapLayer = this.map.getLayer("ELAPAS");
        if (this.rootMapLayer.loaded){
            this.listLayers(this.rootMapLayer);
        }
        else{
            this.rootMapLayer.on("load", lang.hitch(this, this.listLayers));
        }

        //enlace de eventos (tested this, and it doesn't work for the second filtering select either)
        //this.fieldDijit.on('change', lang.hitch(this, this._handleFieldSelected));
        //this.layerDijit.on('change', lang.hitch(this, this._handleLayerSelected));
    },

listLayers: function() {

        var layerInfos = [];

        layerInfos = array.filter(this.rootMapLayer.layerInfos,function(info,index){
            return info.subLayerIds === null;
        });

        if(layerInfos.length === 0) {
            console.error("No se encontro ninguna capa para el servicio de mapa seleccionado");
            return;
        }

        var layersStore = new Memory({
            data: layerInfos
        });

        this.layerDijit.set('store', layersStore);
    },

处理选择的代码在第一个filteringSelect中更改名为layerDijit并加载第二个(FieldDijit)的数据:

_handleLayerSelected: function () {
        var selectedLayer = this.layerDijit.item;

        if(this.getSelectedLayerUrl() === null) {
            return;
        }

        //Se limpia el campo actual
        this.fieldDijit.set("value", "");

        //Se arma la url del layer específico para traer la información de la capa (sus campos)
        var layerUrl = this.rootMapLayer.url + "/" + selectedLayer.id;

        esri.request({
            url: layerUrl,
            content: {
                f: "json"
            },
            handleAs: "json",
            callbackParamName: 'callback',
            load: lang.hitch(this, '_handleLayerInfo'),
            error: lang.hitch(this, '_handleLayerInfoError')
        });
    },
_handleLayerInfo: function(data) {
        var layerInfo = data;
        if (!layerInfo.fields) {
            console.error("No se pudo obtener la información de los campos de la capa");
            return;
        }

        var fieldsStore = new Memory({
            data: layerInfo.fields
        });

        this.fieldDijit.set('store', fieldsStore);
    },

    getSelectedLayerUrl: function(){
        var selectedLayer = this.layerDijit.item;
        if(!selectedLayer) {
            return null;
        }
        //Se arma la url del layer específico para traer la información de la capa (sus campos)
        return this.rootMapLayer.url + "/" + selectedLayer.id;
    },

    _handleLayerInfoError: function(err){
        console.error(err);
    },

未被触发的函数,用于处理第二次过滤的se更改事件的函数选择:

_handleFieldSelected: function () {
        alert("doesn't get fired");
        /*var selectedField = this.fieldDijit.item;

        if(!selectedField) {
            return;
        } */
    },

你能就这个问题给我一些建议吗?我做错了什么?。

提前致谢

2 个答案:

答案 0 :(得分:3)

主教,谢谢你的回答,我想我不清楚我的问题,我明白当用户(或后台的某些东西)改变所选项目时,“onChange”事件应该被解雇FilteringSelect,所以我的问题是当用户从第二个FilteringSelect控件中选择一个项时,它的onchange事件没有被触发。

正如你所建议我尝试了一个更简单的例子(带有硬编码的Memory对象)并且它确实有效,所以我开始挖掘更多,并意识到问题出在我的记忆对象上,

当您声明一个Memory对象时,您必须确保在数组集合对象中存在一个ID,如下一个示例所示:

var stateStore = new Memory({
            data: [
                {name:"Alabama" id:"AL"},
                {name:"Alaska", id:"AK"},
                {name:"American Samoa", id:"AS"},
                {name:"Arizona", id:"AZ"},
                {name:"Arkansas", id:"AR"},
                {name:"Armed Forces Europe", id:"AE"},
                {name:"Armed Forces Pacific", id:"AP"},
                {name:"Armed Forces the Americas", id:"AA"},
                {name:"California", id:"CA"},
                {name:"Colorado", id:"CO"},
                {name:"Connecticut", id:"CT"},
                {name:"Delaware", id:"DE"}
            ]
        });
        this.fieldDijit.set('store', stateStore);

如果你没有在内存对象声明中明确告诉它,那么就会有一个名为“id”的字段。在我的例子中,我在第二个filteringSelect中为内存对象提供的数组没有一个名为“id”的字段

所以我改变了:

var fieldsStore = new Memory({
            data: layerInfo.fields
        });

有:

var fieldsStore = new Memory({
            idProperty: "name", //added this
            data: layerInfo.fields
        });

现在,当第二个filterin选择中的选定项目发生更改时,会触发该事件。

答案 1 :(得分:1)

根据我正在阅读的内容,我认为你期待这段代码:

this.fieldDijit.set('store', fieldsStore);

导致co-dependent select排列中的第二个选择触发其更改事件 - 毕竟,选择已经“更改”,因为它具有不同的商店。

但这不是改变事件的意思。更改事件表示用户已更改所选值。因此,在设置新商店后,如果您在第二个下拉列表中选择一个值,则应该触发您的更改处理程序。

这是一个我认为可以将你的内容简化为最简单元素的例子。请注意,当您选择第一个框的值时,第二个商店的更改但其onchange事件不会触发(如预期的那样)。但是当你选择第二个框的值时,它的onchange会触发(如预期的那样):

<!DOCTYPE html>
<html>
    <head>
        <link href='//ajax.googleapis.com/ajax/libs/dojo/1.9.1/dijit/themes/claro/claro.css' rel='stylesheet' type='text/css' />
        <script src='//ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js'></script>
    </head>
    <body class='claro'>
        <div data-dojo-id='s1' data-dojo-type='dojo/store/Memory' data-dojo-props='data:[{id:1,name:"A"}]'></div>
        <div data-dojo-id='s2' data-dojo-type='dojo/store/Memory' data-dojo-props='data:[{id:1,name:"C"}]'></div>
        <select data-dojo-id='first' data-dojo-type='dijit/form/ComboBox' data-dojo-props='store:s1'>
            <script type='dojo/method' event='onChange'>
                second.set('store', s2);
            </script>
        </select>

        <select data-dojo-id='second' data-dojo-type='dijit/form/ComboBox'>
            <script type='dojo/method' event='onChange'>
                alert('I am changed');
            </script>
        </select>

        <script type='text/javascript'>
        require(['dojo/ready', 'dojo/parser'], function (ready, Parser) {
            ready(function () {
                Parser.parse().then(function () {
                });
            });
        });
        </script>
    </body>
</html>

如果我不理解你所描述的错误,你能发送一个更简单的测试用例吗?