如何使用AngularJS'ui-router更新查询参数来更新地址栏URL,以便在刷新页面时保持状态?
目前,只要输入发生变化,我就会使用$state.transitionTo('search', {q: 'updated search term'})
,但问题是这会重新加载控制器,重新绘制窗口并丢失任何文本输入焦点。
有没有办法更新stateParams并将其同步到窗口URL?
答案 0 :(得分:77)
我在使用.transitionTo时出现问题,直到我更新到ui-router 0.2.14。 0.2.14使用如下调用正确更改位置栏(不重新加载控制器):
$state.transitionTo('search', {q: 'updated search term'}, { notify: false });
答案 1 :(得分:28)
编辑:今天又玩了一些,并意识到角度ui-router有一个类似于本机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更改时重新加载。
答案 2 :(得分:27)
2015年5月19日更新
从ui-router 0.2.15开始,解决了在查询参数更改时重新加载状态的问题。但是,新更新使用查询参数打破了历史API的后退和前进功能。我无法为此找到解决方法。
<强>原始强>
周杰伦的回答对我没有用,也没有其他答案。尝试在浏览器历史记录中来回时,试图听$locationChangeStart
会导致问题,因为这会导致我运行代码两次:一次是新状态发生变化,另一次是$loationChangeStart
被激活。
我尝试使用reloadOnSearch=false
,但即使网址路径发生变化,我也会prevented state changes。所以我最终通过以下方式让它工作:
当您更改$location.search()
以更新查询参数时,请使用"hack"暂时禁用搜索重新加载,设置查询参数,然后重新启用重新加载。
$state.current.reloadOnSearch = false;
$location.search('query', [1,2]);
$timeout(function () {
$state.current.reloadOnSearch = undefined;
});
这将确保查询参数更改不会重新加载状态,并且url路径更改将正确地重新加载状态。
但是,当查询参数是网址的一部分时,这并没有让浏览器历史记录更改状态(知道查询参数何时更改为重新读取URL所需)。所以我还必须将每个查询参数的名称添加到state的url
属性中。
$locationProvider.html5Mode(true);
$stateProvider
.state('home', {
url: '/?param1¶m2¶m3',
templateUrl: 'home.html',
controller: 'homeCtrl as home',
});
当以这种方式列出时,网址上的任何参数名称都是可选的,但是当点击浏览器上的后退和前进按钮时,对这些参数名称的任何更改都将重新加载状态。
希望其他人觉得这很有用,并且它不会花费多天时间来弄清楚如何去做(就像我一样)。