Angularjs $location service apparently not parsing

2019-01-17 14:55发布

I'm using angular in an application which is, basically, a table with search results. Access to this table can be achieved via an url like http://myapp/?client=clientName

An angular controller is instantiated for the table, among other things, for opening a modal dialog (also angular-based with bootstrap-ui) with the row details.

These row details are brought via a service which has some common functionality for both controllers: the one for the table and the one for the modal.

Now, within this service, I have the following snippet to retrieve:

service.fetchRelatedElements = function(element, cb) {
  var url = '/search.json?results=20&type='+element.type;
  if ($location.search()['client']) {
    url += '&client=' + $location.search('client');
  }
  return doFetch(url, cb); // actual server json GET
};

The goal is to know if the table already has this specific client parameter set as a filter.

If I put a breakpoint at the beginning of this call, I see that $location.absUrl() returns the current browser URL (which, in my case, has the client parameter I'm interested in).

But $location.search() returns an empty object.

I am injecting the $location service within my service with the defaults (that is, not configuring it by a .config() call). And, as doc says:

The $location service parses the URL in the browser address bar (based on the window.location) and makes the URL available to your application.

Am I missing something? Shouldn't the URL, at this point, be parsed?

Thanks!


UPDATE: I've managed to make it work. The problem was exactly that I wasn't configuring at all the service. I did so because I assumed that in that way it would take defaults, but it seems that that's not the way it works.

5条回答
爷、活的狠高调
2楼-- · 2019-01-17 15:00

The API for $location.search is pretty confusing. Calling

$location.search('client');

will set the search object to {client: true} and return $location. Furthermore, you have a typo client instead of 'client', so it's setting search to an empty object. So you probably want:

url += '&client=' + $location.search()['client'];
查看更多
叛逆
3楼-- · 2019-01-17 15:12

If you don't want to specify the base tag, you can specify require base false.

myapp.config(function($locationProvider) {
    $locationProvider.html5Mode({
      enabled: true,
      requireBase: false
    });
});
查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-17 15:14

You can write a function that parses the $window.location.search based on this comment https://github.com/angular/angular.js/issues/7239#issuecomment-42047533

function parseLocation(location) {
    var pairs = location.substring(1).split("&");
    var obj = {};
    var pair;
    var i;

    for (i in pairs) {
        if (pairs[i] === "")
            continue;

        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }

    return obj;
}

$scope.query = parseLocation($window.location.search)['query'];
查看更多
闹够了就滚
5楼-- · 2019-01-17 15:19

When I encountered this problem, another thing that worked for me besides setting the configuration is to add "#" in front of the query string.

So if you are the one creating the query string, then changing
myapp/?client=clientName
to
myapp/#?client=clientName

allowed $location.search() to give me a non-empty object which you can then access each parameter using $location.search()['client']

查看更多
Melony?
6楼-- · 2019-01-17 15:23

I was having the same problem before I configured $locationProvider in my app's module config:

appModule.config(['$locationProvider', function($locationProvider) {
        $locationProvider.html5Mode(true);
    }]);
查看更多
登录 后发表回答