经典工具包的 ExtJS 地理定位用法

ExtJS Geolocation usage for classic toolkit

我正在关注 Sencha Touch tutorial 的地理定位用法,但我需要同时使用 classicmodern 工具包。在 sencha app watch / refresh / build 命令期间,我收到 Ext.util.Geolocation class;

要求的错误
C2008: Requirement had no matching files (Ext.util.Geolocation)
[ERR] BUILD FAILED
[ERR] com.sencha.exceptions.ExBuild: Failed to find any files for /..../WeatherView.js::ClassRequire::Ext.util.Geolocation
[ERR]   at sun.reflect.Delegat
[ERR] ingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

尽管当我尝试 sencha app watch modern 命令时,我收到 Ext.form.field.Text 的错误。我无法在我的应用程序中禁用 textfield 用法。那么地理定位服务的解决方案是什么?

这是发生错误的代码片段:

refreshGeoLocation : function( refresh ) {
    if (!this.geoLocationObj || (true == refresh)) {
        Ext.create('Ext.util.Geolocation', {
            autoUpdate: false,
            listeners: {
                locationupdate: function (geo) {
                    Ext.Msg.alert('Refresh Geolocation', 'New latitude: ' + geo.getLatitude() + ' , Longitude: ' + geo.getLongitude(), Ext.emptyFn);
                },
                locationerror: function (geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
                    if (bTimeout) {
                        alert('Timeout occurred');
                    } else {
                        alert('Error occurred');
                    }
                }
            }
        });

        this.geoLocationObj.updateLocation();
    }
}

(*) 教程:https://wtcindia.wordpress.com/2013/02/08/using-yahoo-weather-api-in-sencha-touch/

此错误的原因 (Requirement had no matching files (Ext.util.Geolocation)) 可能在某个地方 (app.js or Application.js) 您需要 这 class Ext.util.Geolocation

Ext.util.Geolocation 仅在 modern 工具包中可用。因此,而不是 app.js 你应该在 modern 文件夹中要求。

For this "Despite when I try to sencha app watch modern command, then I get an error for Ext.form.field.Text."

此 class Ext.form.field.Text 仅可用 classic 工具包。 而不是 modern 工具包中的这个 Ext.form.field.Text you need to use this Ext.field.Text

如果你想在classic工具包中使用Geolocation,那么你需要在classic文件夹中添加自定义class。

有关详细信息,您可以参考我的 ExtJS-GeoLocation 项目。

我希望这能指导您解决错误..

/**
 * Provides a cross browser class for retrieving location information.
 * Source from https://docs.sencha.com/extjs/6.0.0/modern/src/Geolocation.js.html
 * Based on the [Geolocation API Specification](http://dev.w3.org/geo/api/spec-source.html)
 *
 * When instantiated, by default this class immediately begins tracking location information,
 * firing a {@link #locationupdate} event when new location information is available.  To disable this
 * location tracking (which may be battery intensive on mobile devices), set {@link #autoUpdate} to `false`.
 *
 * When this is done, only calls to {@link #updateLocation} will trigger a location retrieval.
 *
 * A {@link #locationerror} event is raised when an error occurs retrieving the location, either due to a user
 * denying the application access to it, or the browser not supporting it.
 *
 * The below code shows a GeoLocation making a single retrieval of location information.
 *
 *      //{GeoLocation} is your application name
 *     var geo = Ext.create('GeoLocation.util.Geolocation', {
 *         autoUpdate: false,
 *         listeners: {
 *             locationupdate: function(geo) {
 *                 Ext.Msg.alert('Success', `New latitude: ${geo.getLatitude()} <br>New Longitude: ${geo.getLongitude()}`);
 *             },
 *             locationerror: function(geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
 *                 if(bTimeout){
 *                     Ext.Msg.alert('Error', 'Timeout occurred.');
 *                 } else {
 *                      Ext.Msg.alert('Error', 'Error occurred');
 *                 }
 *             }
 *         }
 *     });
 *     geo.updateLocation();
 */
//{GeoLocation} is your application name
Ext.define('GeoLocation.util.Geolocation', {
    extend: 'Ext.Evented',

    alternateClassName: ['Geolocation'],

    config: {
        /**
         * @event locationerror
         * Raised when a location retrieval operation failed.
         *
         * In the case of calling updateLocation, this event will be raised only once.
         *
         * If {@link #autoUpdate} is set to `true`, this event could be raised repeatedly.
         * The first error is relative to the moment {@link #autoUpdate} was set to `true`
         * (or this {@link Ext.util.Geolocation} was initialized with the {@link #autoUpdate} config option set to `true`).
         * Subsequent errors are relative to the moment when the device determines that it's position has changed.
         * @param {Ext.util.Geolocation} this
         * @param {Boolean} timeout
         * Boolean indicating a timeout occurred
         * @param {Boolean} permissionDenied
         * Boolean indicating the user denied the location request
         * @param {Boolean} locationUnavailable
         * Boolean indicating that the location of the device could not be determined.
         * For instance, one or more of the location providers used in the location acquisition
         * process reported an internal error that caused the process to fail entirely.
         * @param {String} message An error message describing the details of the error encountered.
         *
         * This attribute is primarily intended for debugging and should not be used
         * directly in an application user interface.
         */

        /**
         * @event locationupdate
         * Raised when a location retrieval operation has been completed successfully.
         * @param {Ext.util.Geolocation} this
         * Retrieve the current location information from the GeoLocation object by using the read-only
         * properties: {@link #latitude}, {@link #longitude}, {@link #accuracy}, {@link #altitude}, {@link #altitudeAccuracy}, {@link #heading}, and {@link #speed}.
         */

        /**
         * @cfg {Boolean} autoUpdate
         * When set to `true`, continually monitor the location of the device (beginning immediately)
         * and fire {@link #locationupdate} and {@link #locationerror} events.
         */
        autoUpdate: true,

        /**
         * @cfg {Number} frequency
         * The frequency of each update if {@link #autoUpdate} is set to `true`.
         */
        frequency: 10000,

        /**
         * @cfg {Number} latitude
         * Read-only property representing the last retrieved
         * geographical coordinate specified in degrees.
         * @readonly
         */
        latitude: null,

        /**
         * @cfg {Number} longitude
         * Read-only property representing the last retrieved
         * geographical coordinate specified in degrees.
         * @readonly
         */
        longitude: null,

        /**
         * @cfg {Number} accuracy
         * Read-only property representing the last retrieved
         * accuracy level of the latitude and longitude coordinates,
         * specified in meters.
         *
         * This will always be a non-negative number.
         *
         * This corresponds to a 95% confidence level.
         * @readonly
         */
        accuracy: null,

        /**
         * @cfg {Number} altitude
         * Read-only property representing the last retrieved
         * height of the position, specified in meters above the ellipsoid
         * [WGS84](http://dev.w3.org/geo/api/spec-source.html#ref-wgs).
         * @readonly
         */
        altitude: null,

        /**
         * @cfg {Number} altitudeAccuracy
         * Read-only property representing the last retrieved
         * accuracy level of the altitude coordinate, specified in meters.
         *
         * If altitude is not null then this will be a non-negative number.
         * Otherwise this returns `null`.
         *
         * This corresponds to a 95% confidence level.
         * @readonly
         */
        altitudeAccuracy: null,

        /**
         * @cfg {Number} heading
         * Read-only property representing the last retrieved
         * direction of travel of the hosting device,
         * specified in non-negative degrees between 0 and 359,
         * counting clockwise relative to the true north.
         *
         * If speed is 0 (device is stationary), then this returns `NaN`.
         * @readonly
         */
        heading: null,

        /**
         * @cfg {Number} speed
         * Read-only property representing the last retrieved
         * current ground speed of the device, specified in meters per second.
         *
         * If this feature is unsupported by the device, this returns `null`.
         *
         * If the device is stationary, this returns 0,
         * otherwise it returns a non-negative number.
         * @readonly
         */
        speed: null,

        /**
         * @cfg {Date} timestamp
         * Read-only property representing when the last retrieved
         * positioning information was acquired by the device.
         * @readonly
         */
        timestamp: null,

        //PositionOptions interface
        /**
         * @cfg {Boolean} allowHighAccuracy
         * When set to `true`, provide a hint that the application would like to receive
         * the best possible results. This may result in slower response times or increased power consumption.
         * The user might also deny this capability, or the device might not be able to provide more accurate
         * results than if this option was set to `false`.
         */
        allowHighAccuracy: false,

        /**
         * @cfg {Number} timeout
         * The maximum number of milliseconds allowed to elapse between a location update operation
         * and the corresponding {@link #locationupdate} event being raised.  If a location was not successfully
         * acquired before the given timeout elapses (and no other internal errors have occurred in this interval),
         * then a {@link #locationerror} event will be raised indicating a timeout as the cause.
         *
         * Note that the time that is spent obtaining the user permission is **not** included in the period
         * covered by the timeout.  The `timeout` attribute only applies to the location acquisition operation.
         *
         * In the case of calling `updateLocation`, the {@link #locationerror} event will be raised only once.
         *
         * If {@link #autoUpdate} is set to `true`, the {@link #locationerror} event could be raised repeatedly.
         * The first timeout is relative to the moment {@link #autoUpdate} was set to `true`
         * (or this {@link Ext.util.Geolocation} was initialized with the {@link #autoUpdate} config option set to `true`).
         * Subsequent timeouts are relative to the moment when the device determines that it's position has changed.
         */
        timeout: Infinity,

        /**
         * @cfg {Number} maximumAge
         * This option indicates that the application is willing to accept cached location information whose age
         * is no greater than the specified time in milliseconds. If `maximumAge` is set to 0, an attempt to retrieve
         * new location information is made immediately.
         *
         * Setting the `maximumAge` to Infinity returns a cached position regardless of its age.
         *
         * If the device does not have cached location information available whose age is no
         * greater than the specified `maximumAge`, then it must acquire new location information.
         *
         * For example, if location information no older than 10 minutes is required, set this property to 600000.
         */
        maximumAge: 0,

        /**
         * @private
         */
        provider: undefined
    },

    updateMaximumAge: function() {
        if (this.watchOperation) {
            this.updateWatchOperation();
        }
    },

    updateTimeout: function() {
        if (this.watchOperation) {
            this.updateWatchOperation();
        }
    },

    updateAllowHighAccuracy: function() {
        if (this.watchOperation) {
            this.updateWatchOperation();
        }
    },

    applyProvider: function(config) {
        if (Ext.feature.has.Geolocation) {
            if (!config) {
                if (navigator && navigator.geolocation) {
                    config = navigator.geolocation;
                } else if (window.google) {
                    config = google.gears.factory.create('beta.geolocation');
                }
            }
        } else {
            this.fireEvent('locationerror', this, false, false, true, 'This device does not support Geolocation.');
        }
        return config;
    },

    updateAutoUpdate: function(newAutoUpdate, oldAutoUpdate) {
        var me = this,
            provider = me.getProvider();

        if (oldAutoUpdate && provider) {
            Ext.uninterval(me.watchOperationId);
            me.watchOperationId = null;
        }

        if (newAutoUpdate) {
            if (!provider) {
                me.fireEvent('locationerror', me, false, false, true, null);
                return;
            }

            try {
                me.updateWatchOperation();
            } catch (e) {
                me.fireEvent('locationerror', me, false, false, true, e.message);
            }
        }
    },

    /**
     * @private
     */
    updateWatchOperation: function() {
        var me = this,
            provider = me.getProvider();

        // The native watchPosition method is currently broken in iOS5...

        if (me.watchOperationId) {
            Ext.uninterval(me.watchOperationId);
        }

        function pollPosition() {
            provider.getCurrentPosition(
                Ext.bind(me.fireUpdate, me),
                Ext.bind(me.fireError, me),
                me.parseOptions()
            );
        }

        pollPosition();
        me.watchOperationId = Ext.interval(pollPosition, this.getFrequency());
    },

    /**
     * Executes a onetime location update operation,
     * raising either a {@link #locationupdate} or {@link #locationerror} event.
     *
     * Does not interfere with or restart ongoing location monitoring.
     * @param {Function} callback
     * A callback method to be called when the location retrieval has been completed.
     *
     * Will be called on both success and failure.
     *
     * The method will be passed one parameter, {@link Ext.util.Geolocation}
     * (**this** reference), set to `null` on failure.
     *
     *     geo.updateLocation(function (geo) {
     *         alert('Latitude: ' + (geo !== null ? geo.latitude : 'failed'));
     *     });
     *
     * @param {Object} [scope]
     * The scope (**this** reference) in which the handler function is executed.
     *
     * **If omitted, defaults to the object which fired the event.**
     *
     * @param {Object} [positionOptions] (private) See W3C spec
     */
    updateLocation: function(callback, scope, positionOptions) {
        var me = this,
            provider = me.getProvider();

        var failFunction = function(message, error) {
            if (error) {
                me.fireError(error);
            } else {
                me.fireEvent('locationerror', me, false, false, true, message);
            }
            if (callback) {
                callback.call(scope || me, null, me); //last parameter for legacy purposes
            }
        };

        if (!provider) {
            failFunction(null);
            return;
        }

        try {
            provider.getCurrentPosition(
                //success callback
                function(position) {
                    me.fireUpdate(position);
                    if (callback) {
                        callback.call(scope || me, me, me); //last parameter for legacy purposes
                    }
                },
                //error callback
                function(error) {
                    failFunction(null, error);
                },
                positionOptions || me.parseOptions()
            );
        } catch (e) {
            failFunction(e.message);
        }
    },

    /**
     * @private
     */
    fireUpdate: function(position) {
        var me = this,
            coords = position.coords;

        this.position = position;

        me.setConfig({
            timestamp: position.timestamp,
            latitude: coords.latitude,
            longitude: coords.longitude,
            accuracy: coords.accuracy,
            altitude: coords.altitude,
            altitudeAccuracy: coords.altitudeAccuracy,
            heading: coords.heading,
            speed: coords.speed
        });

        me.fireEvent('locationupdate', me);
    },

    /**
     * @private
     */
    fireError: function(error) {
        var errorCode = error.code;
        this.fireEvent('locationerror', this,
            errorCode == error.TIMEOUT,
            errorCode == error.PERMISSION_DENIED,
            errorCode == error.POSITION_UNAVAILABLE,
            error.message == undefined ? null : error.message
        );
    },

    /**
     * @private
     */
    parseOptions: function() {
        var timeout = this.getTimeout(),
            ret = {
                maximumAge: this.getMaximumAge(),
                enableHighAccuracy: this.getAllowHighAccuracy()
            };

        //Google doesn't like Infinity
        if (timeout !== Infinity) {
            ret.timeout = timeout;
        }
        return ret;
    },

    destroy: function() {
        this.setAutoUpdate(false);
        this.callParent();
    }
});