Отправка данных по маршрутам в Angular


182

Есть ли способ отправить данные в качестве параметра с router.navigate? Я имею в виду, что-то вроде этого примера, как вы можете видеть, что у маршрута есть параметр данных, но при этом он не работает:

this.router.navigate(["heroes"], {some-data: "othrData"})

потому что некоторые данные не являются допустимым параметром. Как я могу это сделать? Я не хочу отправлять параметр с queryParams.


Я думаю, что это должно быть иначе, как в AngularJS, где мы смогли сделать что-то вроде $ state.go ('heroes', {some-data: "otherData"})
Motomine

3 простых способа обмена данными по маршрутам - angulartutorial.net/2017/12/…
Prashobh

Используйте мой подход npmjs.com/package/ngx-navigation-with-data Последний комментарий от меня, лучший для всех
Virendra Yadav

Ответы:


517

В этой теме много путаницы, потому что есть много разных способов сделать это.

Вот соответствующие типы, используемые на следующих снимках экрана:

private route: ActivatedRoute
private router: Router

1) Обязательные параметры маршрутизации:

введите описание изображения здесь

2) Маршрут Необязательные параметры:

введите описание изображения здесь

3) Параметры запроса маршрута:

введите описание изображения здесь

4) Вы можете использовать сервис для передачи данных из одного компонента в другой без использования параметров маршрута вообще.

Для примера см .: https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/

У меня есть плункер этого здесь: https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview


Спасибо за ваш ответ! В чем разница между 2) и 3)? Потому что оба заканчивают тем, что добавили «? Parameter =» в URL. Не могли бы вы привести пример для 4)? Я не могу понять, как это сделать.
Motomine

Я обновил ответ, чтобы показать различные URL-адреса и предоставить ссылку на сообщение в блоге и план действий по передаче данных с помощью службы. URL отличается от необязательных и параметров запроса, как показано выше. Плюс параметры запроса могут быть сохранены между маршрутами.
DeborahK

6
У меня также есть курс Pluralsight по маршрутизации, который охватывает все это: app.pluralsight.com/library/courses/angular-routing/… Вы можете подписаться на бесплатную неделю, если вам нужна дополнительная информация.
DeborahK

3
Данные только «разделяются» внутри исполняемого приложения. Если пользователь обновляет страницу, все приложение перезагружается с сервера, поэтому в приложении не сохраняется прежнее состояние. Думать об этом с точки зрения обычного приложения, когда пользователь обновляет его, все равно что закрывать и открывать приложение. Если вам нужно сохранить состояние после обновления, то вам нужно будет сохранить его где-нибудь, например, в локальном хранилище или на сервере.
DeborahK

2
Просто небольшой намек: routeтип есть ActivatedRoute, а не Router.
Арсен Хачатурян

156

В Angular 7.2.0 появился новый метод

https://angular.io/api/router/NavigationExtras#state

Послать:

this.router.navigate(['action-selection'], { state: { example: 'bar' } });

Вы хотите получать:

constructor(private router: Router) {
  console.log(this.router.getCurrentNavigation().extras.state.example); // should log out 'bar'
}

Вы можете найти дополнительную информацию здесь:

https://github.com/angular/angular/pull/27198

Ссылка выше содержит этот пример, что может быть полезно: https://stackblitz.com/edit/angular-bupuzn


11
Это правильный ответ, учитывая новые функции в Angular 7.
Рэнди

2
При таком подходе, как бы я справился с обновлением браузера пользователем? В этом случае данные в дополнительных элементах навигации, похоже, исчезают, поэтому нет возможности использовать их снова при обновлении.
tobi_b

1
@tobi_b Я думаю, что вы правы, после обновления вы не можете добраться до него. Если вам нужно после обновления, методы в принятом ответе будут лучше.
Вегер Лоран

3
Да, именно поэтому вы можете получить данные только из this.router.getCurrentNavigation () в конструкторе. Если вам это нужно в другом месте, например, внутри ngOnInit (), вы можете получить доступ к данным через "history.state". Из документации: «Состояние передано любой навигации. Это значение будет доступно через объект extras, возвращаемый из router.getCurrentNavigation () во время выполнения навигации. После завершения навигации это значение будет записано в history.state, когда местоположение .go или location.replaceState вызывается перед активацией этого маршрута. "
Вегер Лоран,

8
Также убедитесь, что вы не пытаетесь получить дополнительный объект в ngOnInit()видеthis.router.getCurrentNavigation().extras
hastrb

26

В последней версии angular (7.2+) теперь есть возможность передавать дополнительную информацию с помощью NavigationExtras .

Домашний компонент

import {
  Router,
  NavigationExtras
} from '@angular/router';
const navigationExtras: NavigationExtras = {
  state: {
    transd: 'TRANS001',
    workQueue: false,
    services: 10,
    code: '003'
  }
};
this.router.navigate(['newComponent'], navigationExtras);

newComponent

test: string;
constructor(private router: Router) {
  const navigation = this.router.getCurrentNavigation();
  const state = navigation.extras.state as {
    transId: string,
    workQueue: boolean,
    services: number,
    code: string
  };
  this.test = "Transaction Key:" + state.transId + "<br /> Configured:" + state.workQueue + "<br /> Services:" + state.services + "<br /> Code: " + state.code;
}

Вывод

введите описание изображения здесь

Надеюсь, это поможет!


1

@ dev-nish Ваш код работает с небольшими изменениями. сделать

const navigationExtras: NavigationExtras = {
  state: {
    transd: 'TRANS001',
    workQueue: false,
    services: 10,
    code: '003'
  }
};

в

let navigationExtras: NavigationExtras = {
  state: {
    transd: '',
    workQueue: ,
    services: ,
    code: ''
  }
};

затем, если вы хотите специально отправить тип данных, например, JSON, в результате заполнения формы, вы можете отправить данные так же, как описано выше.


0

В navigateExtra мы можем передать только какое-то конкретное имя в качестве аргумента, в противном случае он показывает ошибку, как показано ниже: Например, здесь я хочу передать ключ клиента в роутере, и я передаю вот так:

this.Router.navigate(['componentname'],{cuskey: {customerkey:response.key}});

но он показывает некоторую ошибку, как показано ниже:

Argument of type '{ cuskey: { customerkey: any; }; }' is not assignable to parameter of type 'NavigationExtras'.
  Object literal may only specify known properties, and 'cuskey' does not exist in type 'NavigationExt## Heading ##ras'

,

Решение: мы должны написать так:

this.Router.navigate(['componentname'],{state: {customerkey:response.key}});

-2

Лучшее, что я нашел в интернете, это ngx-navigation-with-data . Это очень просто и хорошо для навигации данных от одного компонента к другому компоненту. Вы должны просто импортировать класс компонента и использовать его очень простым способом. Предположим, у вас есть дом и о компоненте, и вы хотите отправить данные тогда

ДОМАШНИЙ КОМПОНЕНТ

import { Component, OnInit } from '@angular/core';
import { NgxNavigationWithDataComponent } from 'ngx-navigation-with-data';

@Component({
 selector: 'app-home',
 templateUrl: './home.component.html',
 styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

constructor(public navCtrl: NgxNavigationWithDataComponent) { }

 ngOnInit() {
 }

 navigateToABout() {
  this.navCtrl.navigate('about', {name:"virendta"});
 }

}

О КОМПОНЕНТЕ

import { Component, OnInit } from '@angular/core';
import { NgxNavigationWithDataComponent } from 'ngx-navigation-with-data';

@Component({
 selector: 'app-about',
 templateUrl: './about.component.html',
 styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {

 constructor(public navCtrl: NgxNavigationWithDataComponent) {
  console.log(this.navCtrl.get('name')); // it will console Virendra
  console.log(this.navCtrl.data); // it will console whole data object here
 }

 ngOnInit() {
 }

}

Для любого запроса следуйте https://www.npmjs.com/package/ngx-navigation-with-data

Комментарий за помощь.


Передает ли данные в виде параметров или просто в фоновом режиме?
Марий Малик

Я не мог понять @MariumMalik Не могли бы вы спросить в описательной форме?
Вирендра Ядав

Да, это так @MariumMalik
Yadav

3
Вы, кажется, автор этого, а не "Я нашел в Интернете"? Вас также просят не спамить это в потоке Angular 7, который реализует аналогичную функциональность ( github.com/angular/angular/pull/27198 )
IrishDubGuy
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.