使用Angular ui-router设置URL查询参数而不更改状态

Pet*_*ron 65 url query-parameters angularjs angular-ui-router

如何使用AngularJS'ui-router更新地址栏URL以更新查询参数以在刷新页面时保持状态?

目前,我$state.transitionTo('search', {q: 'updated search term'})在输入更改时使用,但问题是这会重新加载控制器,重绘窗口并丢失任何文本输入焦点.

有没有办法更新stateParams并将其同步到窗口URL?

pmo*_*ont 78

我在.transitionTo 遇到麻烦,直到我更新到ui-router 0.2.14.0.2.14使用如下调用正确更改位置栏(无需重新加载控制器):

$state.transitionTo('search', {q: 'updated search term'}, { notify: false });
Run Code Online (Sandbox Code Playgroud)

  • 最好的答案,最少的hackish (2认同)
  • 但是当我使用这个解决方案时,它似乎会重新加载组件.我使用的是最新的Angular UI路由器1.0.0.beta3 (2认同)

Jay*_*ehr 28

编辑:今天玩了更多,并意识到角度ui路由器有一个类似于本机routerProvider的选项:"reloadOnSearch".

https://github.com/angular-ui/ui-router/wiki/Quick-Reference#options-1

true默认设置为,但如果将其设置为false您的状态,则在更改查询参数时不会发生状态更改.然后你可以调用$location.search(params);或者$location.search('param', value);URL会改变,但是ui-router不会重新构建整个控制器/视图.您可能还需要$locationChangeStart在根作用域上侦听事件,以处理应用程序中的后退和前进历史记录操作,因为这些操作也不会导致状态更改.

我也正在侦听$stateChangeSuccess控制器范围内的事件,以捕获页面/路径的初始负载.

关于github有一些关于使用此功能和路径更改(不仅仅是URL更改)的讨论:https://github.com/angular-ui/ui-router/issues/125但是我从来没有测试过这个用例特定于查询字符串参数.

我的回答的先前版本提到了这个github问题:

https://github.com/angular-ui/ui-router/issues/562

但这是一个稍微独立的问题,特别是在没有非模态状态变化的情况下,显示一个状态超过另一个状态.我在那个问题上试过了补丁,但很明显它不是为了防止整个状态在URL更改时重新加载.

  • 你做$ location.search后如何掌握新的搜索参数?在执行$ location.search后,似乎$ stateParams没有更新,$ routeParams没有新值. (6认同)

Ste*_*ert 27

2015年5月19日更新

从ui-router 0.2.15开始,解决了在查询参数更改时重新加载状态的问题.但是,新更新使用查询参数打破了历史API的后退和前进功能.我无法找到解决方法.

原版的

周杰伦的回答对我不起作用,也没有其他答案.尝试$locationChangeStart在浏览器历史记录中来回时听到引起的问题,因为这会导致我运行代码两次:一次是新状态改变而另一次因为$loationChangeStart被解雇.

我尝试使用reloadOnSearch=false,但即使URL路径发生变化,也可以防止状态更改.所以我最终通过执行以下操作来实现它:

当您更改$location.search()以更新查询参数时,使用"hack"暂时禁用搜索重新加载,设置查询参数,然后重新启用重新加载.

$state.current.reloadOnSearch = false;

$location.search('query', [1,2]);

$timeout(function () {
  $state.current.reloadOnSearch = undefined;
});
Run Code Online (Sandbox Code Playgroud)

这将确保查询参数更改不会重新加载状态,并且url路径更改将正确地重新加载状态.

但是,当查询参数是url的一部分时,这并没有让浏览器历史记录更改状态(知道查询参数何时更改为重新读取URL所需).所以我还必须将每个查询参数的名称添加到状态url属性中.

$locationProvider.html5Mode(true);

$stateProvider
  .state('home', {
    url: '/?param1&param2&param3',
    templateUrl: 'home.html',
    controller: 'homeCtrl as home',
  });
Run Code Online (Sandbox Code Playgroud)

当以这种方式列出时,URL上的任何参数名称都是可选的,但是当按下浏览器上的后退和前进按钮时,对这些参数名称的任何更改都将重新加载状态.

希望其他人觉得这很有用,并且不需要多天才能弄清楚如何去做(就像我做的那样).