2017-08-14 9 views
1

私はいくつかのフィルタを持つ検索フォームを持っています。それらは、テキスト入力、チェックボックス、ラジオボタンで配布されます。これらのフィルタを使用すると、URLのクエリ文字列を更新する必要があります。角4:URLのクエリ文字列を更新できません

Iは、以下のケースを有することができる。このような配列に翻訳される

http://example.com/search?myFilter=1&myFilter=2&myFilter=3

:myFilterを= [ '1'、 '2'、 '3']。次のように

クエリ文字列を更新するためのコードは次のとおり

this.router.navigate([], {queryParams: myNewQueryString, relativeTo: this.routerActive}); 

「this.router」はActivatedRouteのインスタンスであり、「myNewQueryString」はクエリ文字列の新しいパラメータを含むオブジェクトである場合。このコードが行うことは、ルートを自身にリダイレクトしてクエリ文字列を更新することです。

クエリ文字列を新しいフィルタで更新する前に、既にURLの一部であるフィルタを失わないようにする必要があります。だから、私は、クエリ文字列を読んで、必要な変更を加えてからURLに値を返すだけです。

は、私はこのコードを使用して、クエリ文字列を読み込むには:私は、私は必要な変更を行い、上に移動を開始できることから、

const currentQueryString: any = this.routerActive.snapshot.queryParams; 

を、しかし、問題は、このオブジェクトのプロパティを変更しようとすることで、アンギュラは私に次のエラーを与える:

TypeError: Cannot assign to read only property 'parameter' of object

このエラーはのプロパティので起こる:

this.routerActive.snapshot.queryParams 

すべて読み取り専用なので、直接修正することはできません。

const newQueryString: any = {}; 

for (const key in currentQueryString) { 
    if (currentQueryString.hasOwnProperty(key)) { 
     newQueryString[key] = currentQueryString[key]; 
    } 
} 

今、私はそれに変更を加えることができ、現在のクエリ文字列のコピーを持っている:私は何をする必要があることは、このように、新しいオブジェクトにプロパティをコピーすることです。問題は、配列に複数の値がある場合、クエリ文字列が更新されないということです。最初の値だけ更新されます。

これはバグですか?これにはより良いアプローチがありますか?

私が働いている完全なコードはこれです:

//query is an object like: { 'param' : 'value' } 
updateQueryString(query: any): void { 
    const currentQueryString: any = this.routerActive.snapshot.queryParams; 
    const newQueryString: any = {}; 

    //Copy the current query string 
    for (const key in currentQueryString) { 
     if (currentQueryString.hasOwnProperty(key)) { 
      newQueryString[key] = currentQueryString[key]; 
     } 
    } 

    // Apply the new filter to the copy of the query string 
    for (const key in query) { 
     if (query.hasOwnProperty(key)) { 
      if (newQueryString[key] instanceof Array) { 
       newQueryString[key].push(query[key]); 
      } else { 
       const filter = []; 
       filter.push(query[key]); 
       newQueryString[key] = filter; 
      } 
     } 
    } 

    this.router.navigate([], {queryParams: newQueryString, relativeTo: this.routerActive}); 
    this.search(newQueryString); 
} 

私は、この関数で行う必要がありますが、今、私は唯一のURLに変更を加えたい他の検証があります。私はこの質問の冒頭で述べたシナリオを持つことができるので、すべてのパラメータをArrayとして扱います。

答えて

1

現在のクエリ文字列から新しい文字列にコピーする際に問題が発生したようです。何らかの理由で、配列の新しいインスタンスを提供して、Angularが変更を理解してURLに適用できるようにする必要があります。

は、この新しいインスタンスを提供するために、我々は変更することができます。

この:この中へ

newQueryString[key] = currentQueryString[key]; 

:問題が解決された配列の新しいインスタンスを作成することにより

newQueryString[key] = Array.from(currentQueryString[key]); 

と必要な変更がURLに反映されるようになりました。

このcopy-copy-apply-applyクエリー文字列を問題なく処理するには、いくつかのバリデーションが必要ですが、問題が解決したら、これらの詳細はあまり関係ありません。 ActivatedRoute。

誰かがこのような問題を抱えたら、明らかにオブジェクトの新しいインスタンスで作業してください。

関連する問題