我试图更新(添加,删除)queryParams从一个组件。在angularJS中,它曾经是可能的,这要归功于:
$location.search('f', 'filters[]'); // setter
$location.search()['filters[]']; // getter
我有一个应用程序的列表,用户可以过滤,顺序等,我想设置在url的queryParams所有过滤器激活,这样他就可以复制/粘贴url或与他人共享。
但是,我不希望每次选择筛选器时都重新加载页面。
新路由器能做到吗?
您可以使用新的查询参数导航到当前路由,这不会重新加载页面,但会更新查询参数。
类似于(在组件中):
import {ActivatedRoute, Router} from '@angular/router';
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
) { }
public myMethodChangingQueryParams() {
const queryParams: Params = { myParam: 'myNewValue' };
this.router.navigate(
[],
{
relativeTo: activatedRoute,
queryParams: queryParams,
queryParamsHandling: 'merge', // remove to replace all query params by provided
});
}
注意,虽然它不会重新加载页面,但它会将一个新条目推送到浏览器的历史记录中。如果你想在历史记录中替换它,而不是在那里添加新的值,你可以使用{queryParams: queryParams, replaceUrl: true}。
编辑:
正如评论中已经指出的,[]和relativeTo属性在我最初的示例中缺失,因此它也可以更改路由,而不仅仅是查询参数。正确的this.router.navigate用法如下:
this.router.navigate(
[],
{
relativeTo: this.activatedRoute,
queryParams: { myParam: 'myNewValue' },
queryParamsHandling: 'merge'
});
将新的参数值设置为null将从URL中删除参数。
在Angular 5中,你可以通过解析当前url来轻松获取和修改urlTree的副本。这将包括查询参数和片段。
let urlTree = this.router.parseUrl(this.router.url);
urlTree.queryParams['newParamKey'] = 'newValue';
this.router.navigateByUrl(urlTree);
修改查询参数的“正确方法”可能是使用
创建一个新的UrlTree从当前,同时让我们修改它使用NavigationExtras。
import { Router } from '@angular/router';
constructor(private router: Router) { }
appendAQueryParam() {
const urlTree = this.router.createUrlTree([], {
queryParams: { newParamKey: 'newValue' },
queryParamsHandling: "merge",
preserveFragment: true });
this.router.navigateByUrl(urlTree);
}
为了以这种方式删除查询参数,可以将其设置为undefined或null。
首先,我们需要从angular router导入router模块,并声明它的别名
import { Router } from '@angular/router'; ---> import
class AbcComponent implements OnInit(){
constructor(
private router: Router ---> decalre alias name
) { }
}
1. 您可以使用“router”更改查询参数。函数并传递查询参数
this.router.navigate([], { queryParams: {_id: "abc", day: "1", name: "dfd"}
});
它将更新当前即激活路由中的查询参数
下面将重定向到abc页面_id,日
和name作为查询参数
this.router。导航([' / abc '], {queryParams: {_id:“abc”,天:“1”,名称:
“目前”}
});
它将更新“abc”路由中的查询参数以及三个查询参数
获取查询参数:-
import { ActivatedRoute } from '@angular/router'; //import activated routed
export class ABC implements OnInit {
constructor(
private route: ActivatedRoute //declare its alias name
) {}
ngOnInit(){
console.log(this.route.snapshot.queryParamMap.get('_id')); //this will fetch the query params
}
大多数人投票的答案在一定程度上对我有用。浏览器的url保持不变,但我的routerLinkActive在导航后不再工作。
我的解决方案是使用lotit .go:
import { Component } from "@angular/core";
import { Location } from "@angular/common";
import { HttpParams } from "@angular/common/http";
export class whateverComponent {
constructor(private readonly location: Location, private readonly router: Router) {}
addQueryString() {
const params = new HttpParams();
params.append("param1", "value1");
params.append("param2", "value2");
this.location.go(this.router.url.split("?")[0], params.toString());
}
}
我使用HttpParams来构建查询字符串,因为我已经使用它与httpClient一起发送信息。但你可以自己构建。
this._router.url.split("?")[0],是从当前url中删除所有之前的查询字符串。
我最终把urlTree和location.go结合起来
const urlTree = this.router.createUrlTree([], {
relativeTo: this.route,
queryParams: {
newParam: myNewParam,
},
queryParamsHandling: 'merge',
});
this.location.go(urlTree.toString());
不确定toString是否会导致问题,但不幸的是location。Go似乎是基于字符串的。
Angular的Location服务应该在与浏览器的URL交互时使用,而不是用于路由。这就是为什么我们要使用位置服务。
angular HttpParams用于创建查询参数。请记住HttpParams是不可变的,这意味着在创建值时它必须被链接。
最后,使用this._location。replaceState更改为URL,而无需重新加载页面/路由和原生js位置。获取没有参数的url的路径,以每次重置参数。
constructor(
private _location: Location,
) {}
...
updateURLWithNewParamsWithoutReloading() {
const params = new HttpParams().appendAll({
price: 100,
product: 'bag'
});
this._location.replaceState(
location.pathname,
params.toString()
);
}
我遇到过一个有趣的情况,我们对所有的路线只使用了一个组件。这是路线的样子:
const routes: Routes = [
{
path: '',
component: HomeComponent,
children: [
{ path: 'companies', component: HomeComponent },
{ path: 'pipeline', component: HomeComponent },
// ...
]
},
// ...
];
基本上,paths / /companies和/pipeline都有相同的组件需要加载。而且,由于Angular会阻止组件在DOM中之前被加载,所以Router的navigate方法会返回一个总是以null解析的Promise。
为了避免这种情况,我不得不使用onSameUrlNavigation。通过设置这个值为'reload',我设法使路由器导航到相同的URL与更新的查询字符串参数:
@NgModule({
imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
exports: [RouterModule]
})
你也可以像这样添加行为主体:
refresher$ = new BehaviorSubject(null);
我改变了我的代码:
this.route.queryParamMap.subscribe(some code)
to:
combineLatest([
this.route.queryParamMap,
this.refresher$
])
.pipe(
map((data) => data[0])
)
.subscribe(here is your the same code)
当你需要刷新订阅时,你需要调用这个:
this.refresher$.next(null);
不要忘记添加unsubscribe from the ngOnDestroy