Подтвердить что ты не робот

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

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

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

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

Добавлено:

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

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

4b9b3361

Ответ 1

Начиная с версии 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'] });

Ответ 2

После ответа Роберта я нашел функции в Angular.js. Это buildUrl, forEachSorted и sortedKeys. builUrl также использует функции 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('&');
}

Ответ 3

Как вы можете видеть в исходном коде здесь (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, возможно, вы можете скопировать эти функции из источника в свой код и сделать для этого свой собственный сервис.