Как программно создавать URL с помощью AngularJS

В настоящее время я играю со структурой AngularJS. Я использую сервис $route для глубоких ссылок на мое одностраничное приложение.

Теперь я хотел бы перемещаться внутри моего приложения, скажем, изменяя только часть поиска текущего URL. Это легко сделать с помощью службы $location в JavaScript, но как я могу создать атрибут href из текущего маршрута с заменой только части поиска?

Нужно ли делать это вручную или есть способ AngularJS для этого?

Добавлено:

Конечно, у службы $location есть все методы для вычисления таких URL. Но я не могу использовать его, потому что $location также перемещает окно браузера к новому URL.

Существует еще одна сложность при создании URL-адресов вручную: необходимо проверить, используется ли устаревший #-метод или новый History API. В зависимости от этого, URL должен содержать знак # или нет.

3 ответа

Начиная с версии 1.4 вы можете использовать для этого $ httpParamSerializer:

angular.module('util').factory('urlBuilder', function($httpParamSerializer) {
    function buildUrl(url, params) {
        var serializedParams = $httpParamSerializer(params);

        if (serializedParams.length > 0) {
            url += ((url.indexOf('?') === -1) ? '?' : '&') + serializedParams;
        }

        return url;
    }

    return buildUrl;
});

Использование:

Производить http://url?param1=value1&param2=value2_1&param2=value2_2 позвоните с помощью:

urlBuilder('http://url', { param1: 'value1', param2: ['value2_1', 'value2_2'] });

После ответа Роберта я нашел функции в Angular.js. Это buildUrl, forEachSorted и sortedKeys. buildUrl также использует функции isObject и toJson, которые являются открытыми, поэтому их необходимо изменить на angular.isObject и angular.toJson соответственно.

function forEachSorted(obj, iterator, context) {
    var keys = sortedKeys(obj);
    for (var i = 0; i < keys.length; i++) {
        iterator.call(context, obj[keys[i]], keys[i]);
    }
    return keys;
}

function sortedKeys(obj) {
    var keys = [];
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            keys.push(key);
        }
    }
    return keys.sort();
}

function buildUrl(url, params) {
    if (!params) return url;
    var parts = [];
    forEachSorted(params, function (value, key) {
        if (value == null || value == undefined) return;
        if (angular.isObject(value)) {
            value = angular.toJson(value);
        }
        parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
    });
    return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
}

Как вы можете видеть в исходном коде здесь (v.1.1.0):

https://github.com/angular/angular.js/blob/v1.1.0/src/ngResource/resource.js#L228

и здесь:

https://github.com/angular/angular.js/blob/v1.1.0/src/ngResource/resource.js#L247

Angularjs не использует внутренне encodeURIComponent для управления строками URI, но ни делает доступными используемые функции. Эти функции являются внутренними по отношению к модулю (что я считаю жалким).

Если вы хотите управлять своими URI точно так же, как AngularJS, возможно, вы можете скопировать эти функции из исходного кода в свой код и создать для этого свой собственный сервис.

Другие вопросы по тегам