Google Maps API v3:我可以使用 ExtJS 4.2 在组合框中创建地点自动完成功能吗?

Google Maps API v3: Can I create Place Autocomplete in combobox using ExtJS 4.2?

我已经在 google 上搜索过了,但没有找到解决方案。我已阅读 this 文档,但它仅使用纯 javascript.

我读过 this 来自@Ram 创建的较早的 post,但答案并没有解决我的问题,因为我认为也许还有其他更棘手的方法我没有根据我目前的知识现在达到它。

我尝试使用 php 中的 ajax 来检索预测并摆脱该限制,这是我在 c_places.php 中的 php 代码:

function getPlaces(){
        $address = urlencode($this->input->post('place'));
        $request = file_get_contents("http://maps.google.com/maps/api/geocode/json?address=" . $address . "&sensor=false");
        // $json = json_decode($request, true);
        echo $request;
    }

这是我的 ajax 电话:

Ext.Ajax.request({
    url: 'c_places/getPlaces',
    params: {
        "place" : someplace
    },
    success: function(response, opts) {
        var obj = Ext.decode(response.responseText);
        console.dir(obj);
    },
    failure: function(response, opts) {
        console.info('server-side failure with status code ' + response.status);
    }
});

ajax return 来自 googleapi 的 json obj,但我不知道如何将此 json 放到 data.store 的组合框,因为这会在用户键入位置时动态调用。因此,如果我将 Ext.data.store 放在组合框之前的开头,则组合框仅显示原始商店,而不是用户在键入位置时显示的商店。但是,在你尝试这个 url 之前:http://maps.google.com/maps/api/geocode/json?address="address"&sensor=false

有时这个 url 会给我一个 json 输出,但有时会给我错误 "Server not found"。我不知道为什么,直到我 post 这个 url 告诉我错误,但这不是问题,因为我有另一个技巧来获得 json.

我的问题是: 1. 有没有办法使用 keyup 侦听器调用我的 ajax 从组合框动态加载 json 存储?我的意思是,不使用其他组合框来触发来自另一个组合框的加载。 2. 有没有办法在使用 ExtJS 4.2 时创建这个地方自动完成?或解决此问题的其他想法?

非常感谢任何帮助!

如果我的问题没有聚焦问题或者我的问题过于宽泛或问题陈述不明确,请纠正我。我很乐意编辑我的 post 以提供更多详细信息。

好的,看看下面的这段代码,这里只是使用本地固定数据源,但在您的示例中,您可以使用适当的代理将其指向您的 c_places.php。由于示例中的数据源是固定的,因此它始终返回相同的数据,但在您的实例中,您必须检查输入的值。

Ext.application({
    name: 'Fiddle',

    launch: function() {
        addressModel = Ext.define("Addresses", {
            extend: 'Ext.data.Model',
            proxy: {
                type: 'jsonp',
                url: 'https://jsonp.nodejitsu.com',
                reader: {
                    type: 'json',
                    root: 'results',
                    totalProperty: 'totalCount'
                }
            },

            fields: ['formatted_address']
        });

        var ds = Ext.create('Ext.data.Store', {
            model: 'Addresses'
        });


        var panel = Ext.create('Ext.panel.Panel', {
            renderTo: Ext.getBody(),
            title: 'Search the Addresses',
            width: 600,
            bodyPadding: 10,
            layout: 'anchor',

            items: [{
                xtype: 'combo',
                store: ds,
                displayField: 'title',
                typeAhead: false,
                hideLabel: true,
                hideTrigger: true,
                anchor: '100%',
                enableKeyEvents: true,

                listConfig: {
                    loadingText: 'Searching...',
                    emptyText: 'No matching posts found.',

                    // Custom rendering template for each item
                    getInnerTpl: function() {
                        return '<div class="search-item">{formatted_address}</div>';
                    }
                },

                // override default onSelect to do redirect
                listeners: {
                    select: function(combo, selection) {
                        var address = selection[0];
                        if (address) {
                            alert('you picked ' + address.data.formatted_address);
                        }
                    },
                    keyup: function(combo) {
                        queryString = combo.getValue();
                        console.log(queryString);
                        console.log(addressModel);
                        addressModel.getProxy().setExtraParam('url', 'http://maps.google.com/maps/api/geocode/json?address=' + queryString + '&sensor=false');
                    }
                }
            }, {
                xtype: 'component',
                style: 'margin-top:10px',
                html: 'Live search requires a minimum of 4 characters.'
            }]
        });
    }
});

演示:https://fiddle.sencha.com/#fiddle/g70

为什么不使用 sencha 组合框,而是按照 google api 自动完成文档的建议使用简单的文本输入。 (我首先尝试使用一个普通的文本字段,但没有成功) 然后声明一个组件html如下例,然后赋值render:

xtype: 'component',
html: '<div> <input id="searchTextField" type="text" size="50"> </div>',
listeners: {
    render: function () {
        var input = document.getElementById('searchTextField');
        autocomplete = new google.maps.places.Autocomplete(input, { types: ['geocode'] });
        autocomplete.addListener('place_changed', this.fillInAddress);
    },

现在如果你想在 Panel 中使用这个组件,就会与 Sencha Styles 发生冲突。所以你需要在html文件中加入googleapi的声明。 (我尝试添加到我的 css 文件,但它也不起作用) google 自动完成动态样式:

    <style type="text/css">
        .pac-container {
            z-index: 100000 !important;
        }
    </style>