Отправлять данные по путям маршрутизации в Angular

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

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

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


person Motomine    schedule 01.07.2017    source источник
comment
Думаю, должно быть иначе, как в AngularJS, где мы смогли сделать что-то вроде $ state.go ('heroes', {some-data: otherData})   -  person Motomine    schedule 01.07.2017
comment
Используйте мой подход npmjs.com/package/ngx-navigation-with-data последний мой комментарий, наилучший для всех   -  person Virendra Yadav    schedule 28.11.2018


Ответы (6)


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

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

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

person DeborahK    schedule 01.07.2017
comment
Спасибо за ваш ответ! В чем разница между 2) и 3)? Потому что оба в конечном итоге добавляют? Parameter = в URL-адрес. Не могли бы вы привести пример для 4)? Я не могу понять, как это сделать. - person Motomine; 02.07.2017
comment
Я обновил ответ, чтобы показать разные URL-адреса и предоставить ссылку на сообщение в блоге и плункер о том, как передавать данные с помощью службы. URL отличается необязательными параметрами и параметрами запроса, как показано выше. Плюс параметры запроса могут сохраняться для разных маршрутов. - person DeborahK; 02.07.2017
comment
У меня также есть курс Pluralsight по маршрутизации, который охватывает все это: app.pluralsight.com/library/courses/angular-routing/ Вы можете подписаться на бесплатную неделю, если вас интересует дополнительная информация. - person DeborahK; 02.07.2017
comment
Спасибо! Я думаю, что сделаю это с помощью службы только потому, что я не хочу показывать параметры, но в некоторых случаях другие варианты использования могут сработать. - person Motomine; 02.07.2017
comment
@DeborahK, я думаю, на фото есть небольшая ошибка, которая показывает, как передавать параметры запроса. Это должно быть this.router.navigate(['/products'], {queryParams: {filterBy: 'x', showImage: true}}); - person Egel; 22.09.2017
comment
Вы правы @Egel. Обновлю скриншоты. - person DeborahK; 08.12.2017
comment
передача данных через общую службу не работает, если страница обновляется. данные становятся неопределенными - person Vivek; 14.02.2018
comment
Это произойдет, если вы зарегистрируете службу в модуле, а НЕ в компоненте. У меня есть пример, демонстрирующий это здесь: github.com/DeborahK/MovieHunter - person DeborahK; 14.02.2018
comment
Также стоит отметить, что вариант 2 пытается сериализовать все по URL-адресу, поэтому некоторые сложные объекты теряются (у меня был массив объектов, превращенный в [object Object],[object Object],[object Object]). Кажется, в этом случае услуга - ваш единственный выбор. - person matmo; 22.02.2018
comment
Со стороны Angular это кажется действительно глупым. Иногда разработчики хотят отображать сообщение для своих пользователей, когда они меняют путь. Размещение сообщения в URL-адресе может привести к разного рода взломам и возможностям социальной инженерии. - person CodyBugstein; 24.04.2018
comment
Поэтому и предоставили вариант №4. :-) Вы всегда можете создать сервис, который сохранит любые нужные вам значения. Любой компонент может вводить и получать доступ к этим значениям во всем приложении. И тогда его нет в URL-адресе. - person DeborahK; 24.04.2018
comment
есть ли способ скрыть параметры - person MeVimalkumar; 24.04.2018
comment
@DeborahK Не могли бы вы вкратце объяснить, почему общая служба не создается повторно при обновлении страницы? Я думал, что единственный способ обойти это - использовать локальное хранилище? Я запустил ваш код, но данные на самом деле не «разделяются», поскольку компонент обновляет данные при обновлении через HTTP-вызов - если я не ошибаюсь. - person Standaa - Remember Monica; 02.05.2018
comment
Данные доступны только в исполняющем приложении. Если пользователь обновляет страницу, все приложение перезагружается с сервера, поэтому предыдущее состояние в приложении не сохраняется. Думая об этом с точки зрения обычного приложения, когда пользователь обновляет его, это похоже на закрытие и повторное открытие приложения. Если вам нужно сохранить состояние после обновления, вам нужно будет сохранить его где-нибудь, например, в локальном хранилище или на сервере. - person DeborahK; 02.05.2018
comment
Небольшая подсказка: route тип ActivatedRoute, а не Router. - person Arsen Khachaturyan; 18.05.2018
comment
Вы имеете в виду меня? Мне любопытно, почему вы так думаете? - person DeborahK; 03.09.2019
comment
Спасибо! Хотелось бы, чтобы в официальных документах были четкие примеры, подобные этому. - person rangfu; 18.10.2019
comment
Не используйте скриншоты на SO! Вот почему! - person lllllllllllllIllllIll; 14.11.2019
comment
Уважаемый @DeborahK, ваш пример Plnkr не работает из-за сбоя установки npm. Не могли бы вы исправить и сообщить мне, что все работает правильно? - person LuDeveloper; 16.04.2020
comment
Попробуйте вместо этого: github.com/DeborahK/Angular-Routing @LuDeveloper - person DeborahK; 21.04.2020
comment
В качестве принятого ответа было бы неплохо, если бы вы добавили @ Véger Lóránd его ответ, учитывая пятый метод, использующий состояние. - person TimNode; 16.06.2020
comment
Вот как это должно работать? Я должен заключать в свои чьи-то отличные ответы? - person DeborahK; 17.06.2020
comment
В варианте 4 как я могу отправить метод? Я получаю DataCloneError - person umunBeing; 28.07.2021
comment
Не могли бы вы подробнее рассказать о своем сценарии? Что вы пытаетесь достичь? - person DeborahK; 28.07.2021

В 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 < / а>

person Véger Lóránd    schedule 25.01.2019
comment
Это правильный ответ, учитывая новые функции Angular 7. - person Randy; 05.02.2019
comment
Как при таком подходе обработать обновление браузера пользователем? В этом случае данные в дополнительных функциях навигации, кажется, исчезают, поэтому нет возможности использовать их снова при обновлении. - person tobi_b; 06.02.2019
comment
@tobi_b Думаю, вы правы, после обновления до него не добраться. Если он вам понадобится после обновления, методы из принятого ответа будут лучше. - person Véger Lóránd; 12.02.2019
comment
Совет: посмотрите ответ на stackblitz, чтобы заставить это работать. - person P.Brian.Mackey; 28.02.2019
comment
Читая извлечение для этого, мне не ясно, что он предназначен для замены метода paramMap. От автора извлечения: getCurrentNavigation () вернет текущую выполняемую навигацию. Он вернет null, если в данный момент не выполняется навигация (другими словами, приложение находится в стабильном состоянии). - person IrishDubGuy; 28.03.2019
comment
Да, именно поэтому вы можете получить данные только из this.router.getCurrentNavigation () в конструкторе. Если вам это нужно где-то еще, например, внутри ngOnInit (), вы можете получить доступ к данным через history.state. Из документации: Состояние переходило в любую навигацию. Это значение будет доступно через объект extras, возвращаемый из router.getCurrentNavigation () во время выполнения навигации. После завершения навигации это значение будет записано в history.state при вызове метода location.go или location.replaceState перед активацией этого маршрута. - person Véger Lóránd; 01.04.2019
comment
Также убедитесь, что вы не пытаетесь получить дополнительный объект в ngOnInit() как this.router.getCurrentNavigation().extras - person hastrb; 15.04.2019
comment
Что делать, если вы переходите на внешний URL как route.navigate (['/ externalUrlRedirect', {externalUrl: 'google.com' }], {состояние: {данные {имя: 'mayank'}}}); чем как получить то же самое на другой стороне. Я пробовал history.state, но возвращает только navigationId: 1? - person Mayank; 09.08.2019
comment
@ VégerLóránd @hastrb - почему мы не можем использовать это в ngOnInit() - person Kinley Christian; 04.06.2021
comment
@KinleyChristian Ознакомьтесь с этим ответом, если у вас есть дополнительные вопросы, дайте мне знать! stackoverflow.com/a/54891361/4222504 - person Véger Lóránd; 07.06.2021

В последней версии 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;
}

Вывод

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

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

person dev-nish    schedule 14.03.2019
comment
Я продолжаю получать сообщения об отсутствии навигации. Я пробовал несколько примеров ... - person AppDreamer; 19.11.2020
comment
Это старый, но для будущих посетителей - вы должны вызвать его внутри конструктора. stackoverflow.com/a/54891361/2950032 - person maazadeeb; 28.04.2021
comment
Можете ли вы получить доступ к данным состояния после обновления страницы? - person Sofia; 02.07.2021
comment
хорошо, я только что проверил это сам, и он отлично работает только сразу после перенаправления на новый компонент из старого. После перезагрузки страницы состояние не определено: ( - person Sofia; 02.07.2021

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

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

в

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

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

person Saurav Mohan V    schedule 11.04.2019

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

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}});
person A. PRABIN SARAB    schedule 26.12.2019

Лучшее, что я нашел в Интернете для этого, - это 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

Прокомментируйте, чтобы получить помощь.

person Virendra Yadav    schedule 28.11.2018
comment
Он передает данные в виде параметров или просто в фоновом режиме? - person Marium Malik; 13.02.2019
comment
Я не могу понять @MariumMalik. Не могли бы вы спросить описательно? - person Virendra Yadav; 13.02.2019
comment
Да, @MariumMalik - person Virendra Yadav; 13.02.2019
comment
Вы, кажется, являетесь автором этого, а не я нашел в Интернете? Вас также просят не спамить его в потоке Angular 7, который реализует аналогичные функции (github.com / angular / angular / pull / 27198) - person IrishDubGuy; 28.03.2019