У меня есть угловой компонент, который загружает клиента из базы данных с помощью службы. Вместо того, чтобы возвращаться к базе данных для каждого компонента, я кэширую эти данные в службе как выбранный клиент.
export class ClientService {
Clients: Client[];
constructor() {
this.Clients = [
{
client: 0,
name: "Fred",
street: "Brockton Drive",
address1: null,
address2: null,
city: "SomewhereVille",
zipcode: "1234"
},
{
client: 1,
name: "Wilma",
street: "Somerset Drive",
address1: null,
address2: null,
city: "Elsewhere",
zipcode: "0987"
},
]
}
setCurrentClient(id: number) {
var client = this.Clients[id];
console.info(client);
this.selectedClient.next(client);
}
readonly selectedClient: Subject<Client> = new Subject<Client>()
}
Затем в клиентском компоненте я подписываюсь на параметры маршрута и говорю клиентской службе загрузить клиент и установить selectedClient.
export class ClientComponent implements OnInit {
constructor(private route: ActivatedRoute, private router: Router, private clientService: ClientService) {
console.info("order component activated");
route.paramMap.subscribe((params: ParamMap) => {
const cid = params.get("id");
if (cid)
clientService.setCurrentClient(Number.parseInt(cid));
else
this.selectedClient = undefined;
})
clientService.selectedClient.subscribe((data) => this.selectedClient = data)
}
selectedClient?: Client;
ngOnInit(): void {
}
}
Затем в компоненте «Сведения о клиенте» я подписываюсь на клиентскую службу — выбранный клиент. Это та часть, которая не работает. Поскольку детали не заполняются.
export class ClientDetailsComponent implements OnDestroy {
ClientForm: FormGroup;
token?: Subscription;
constructor(private clientService: ClientService, private formBuilder: FormBuilder) {
this.ClientForm = this.formBuilder.group<Client>(new Client());
this.token = this.clientService.selectedClient.subscribe((data) => {
this.selectedClient = data;
this.ClientForm.setValue(this.selectedClient);
console.info("Client activated");
})
}
ngOnDestroy(): void {
if (this.token) this.token.unsubscribe();
}
selectedClient?: Client;
onSubmit(): void {
}
}
Что я делаю неправильно или против лучших практик, из-за чего это не работает?
P.S. есть пример stackblitz - https://stackblitz.com/github/PhoenixStoneham/TabDataVanishing
Для простоты я удалил весь код базы данных и использую этот массив в качестве заполнителя для примера. Предположим, что метод setclient обычно обращается к базе данных асинхронно.
@E.Maggini, потому что в этой группе вкладок будут не только данные клиента. Там же будет список всех их заказов, возможно финансовые данные и прочее. Поэтому я использую маршрутизацию, чтобы гарантировать, что когда я хочу открыть заказ для клиента, мне не нужно будет его добавлять.
вам не нужно было бы «добавлять», если у вас уже есть эти данные в объекте, хранящемся в клиенте. Просто передайте его с помощью @Input. Вот так может? Ultimatecourses.com/blog/passing-data-angular-components-input
@ E.Maggini, вы можете запустить пример stackblitz и посмотреть на html и маршрутизацию клиентского компонента.
Ты был почти там. Проблема в том, что вы используете тему, а не тему поведения.
Это означает, что он получит следующее значение только после того, как начнет прослушивание.
Таким образом, клиент, который был выбран, не будет иметь своего значения в деталях клиента, потому что он не будет выдавать никакого значения.
Я попробую это утром
Я бы посоветовал вам использовать ngrx и определить Store.
Почему у вас есть роутер-выход в client.component. Не проще ли было бы просто включить их в качестве компонентов, которым вы передаете данные с помощью декоратора @Input? Ваша проблема в том, что тема асинхронна и недоступна, когда вы показываете свои данные.