let httpParams = new HttpParams().set('aaa', '111');
httpParams.set('bbb', '222');
Dlaczego to nie działa? Ustawia tylko „aaa”, a NIE „bbb”
Mam także obiekt {aaa: 111, bbb: 222} Jak mogę ustawić wszystkie wartości bez zapętlania?
UPDATE (to wydaje się działać, ale jak można uniknąć pętli?)
let httpParams = new HttpParams();
Object.keys(data).forEach(function (key) {
httpParams = httpParams.append(key, data[key]);
});
angular
angular-http
Michalis
źródło
źródło
httpParams.set('bbb', '222');
powinno działać. Spróbowałem tego jako pierwszy i byłem bardzo zdezorientowany. Ale zamień tę linię nahttpParams = httpParams.set('bbb','222');
działa. dla tych, którzy ustawiają tylko 2, odpowiedź łańcuchowa od innego użytkownika poniżej jest również miła.Odpowiedzi:
Przed 5.0.0-beta.6
Od wersji 5.0.0-beta.6
źródło
any
. Czy to naprawdę przeznaczenie?{ params: <any>params }
aby uniknąć problemów z kompilatorem TSHttpParams ma być niezmienny. Te
set
iappend
metody nie zmodyfikować istniejącą instancję. Zamiast tego zwracają nowe wystąpienia z zastosowanymi zmianami.To podejście działa dobrze w przypadku łączenia metod:
... chociaż może to być niezręczne, jeśli musisz owinąć którykolwiek z nich w warunkach.
Twoja pętla działa, ponieważ pobierasz odniesienie do zwróconej nowej instancji. Kod, który opublikowałeś, który nie działa, nie działa. Po prostu wywołuje set (), ale nie przechwytuje wyniku.
źródło
@angular/common/http
Wygląda na to, że w nowszych wersjach (5.0 i nowszych ) można użyćfromObject
klawisza do,HttpParamsOptions
aby przekazać obiekt bezpośrednio w:let httpParams = new HttpParams({ fromObject: { aaa: 111, bbb: 222 } });
To tylko tworzy
forEach
pętlę pod maską :this.map = new Map<string, string[]>(); Object.keys(options.fromObject).forEach(key => { const value = (options.fromObject as any)[key]; this.map !.set(key, Array.isArray(value) ? value : [value]); });
źródło
Jeśli chodzi o mnie,
set
metody łańcuchowe to najczystsza drogaźródło
Kilka łatwych alternatyw
Bez używania
HttpParams
obiektówKorzystanie z
HttpParams
obiektówźródło
Inną opcją jest:
źródło
Ponieważ klasa HTTP Params jest niezmienna, musisz połączyć metodę set:
źródło
Dzięki temu możesz uniknąć pętli.
Ponadto sugeruję włączenie funkcji toHttpParams w powszechnie używanej usłudze. Możesz więc wywołać funkcję, aby przekonwertować obiekt na HttpParams .
Aktualizacja:
To jest drugi powód, jeśli użyłeś jednej wspólnej funkcji, takiej jak wspomniana powyżej toHttpParams , możesz ją łatwo usunąć lub wprowadzić zmiany, jeśli to konieczne.
źródło
O ile widzę z wdrożenia na https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts
Musisz podać wartości osobno - nie możesz uniknąć pętli.
Istnieje również konstruktor, który przyjmuje łańcuch jako parametr, ale ma on postać
param=value¶m2=value2
więc nie ma dla Ciebie żadnej umowy (w obu przypadkach zakończysz zapętleniem obiektu).Zawsze możesz zgłosić problem / prośbę o funkcję do angular, co zdecydowanie radzę: https://github.com/angular/angular/issues
PS: Pamiętaj o różnicy między metodami
set
iappend
;)źródło
Ponieważ @MaciejTreder potwierdził, że musimy zapętlić, oto opakowanie, które opcjonalnie pozwoli Ci dodać do zestawu domyślnych parametrów:
Możesz go używać w ten sposób:
źródło
Moja klasa pomocnicza (ts) do konwersji dowolnego złożonego obiektu dto (nie tylko „słownika ciągów”) do HttpParams:
źródło
params.ts
ma własne kodowanie. Sprawdź implementację: github.com/angular/angular/blob/master/packages/common/http/src/…Chciałem tylko dodać, że jeśli chcesz dodać kilka parametrów o tej samej nazwie klucza, na przykład: www.test.com/home?id=1&id=2
Użyj dołączania, jeśli używasz set, nadpisze poprzednią wartość o tej samej nazwie klucza.
źródło
To rozwiązanie działa dla mnie,
let params = new HttpParams(); Object.keys(data).forEach(p => { params = params.append(p.toString(), data[p].toString()); });
źródło