데이터를 "라우터 아웃렛" 하위 구성 요소로 전달
서버로 이동하여 개체를 가져오는 상위 구성 요소가 있습니다.
// parent component
@Component({
selector : 'node-display',
template : `
<router-outlet [node]="node"></router-outlet>
`
})
export class NodeDisplayComponent implements OnInit {
node: Node;
ngOnInit(): void {
this.nodeService.getNode(path)
.subscribe(
node => {
this.node = node;
},
err => {
console.log(err);
}
);
}
그리고 여러 하위 디스플레이 중 하나에서:
export class ChildDisplay implements OnInit{
@Input()
node: Node;
ngOnInit(): void {
console.log(this.node);
}
}
데이터를 단지 데이터에 주입할 수는 없을 것 같습니다.router-outlet
콘솔에 되는 것 .
Can't bind to 'node' since it isn't a known property of 'router-outlet'.
이것은 어느 정도 일리가 있지만, 다음을 어떻게 해야 합니까?
- 상위 구성 요소 내에서 서버의 "노드" 데이터를 가져오시겠습니까?
- 서버에서 검색한 데이터를 하위 라우터 출구로 전달하시겠습니까?
그것은 아닌 것 같습니다.router-outlets
같은 방식으로 일하다
<router-outlet [node]="..."></router-outlet>
유효하지 않습니다.는 터우에의추구추형다에 됩니다.<router-outlet>
그리고 그것을 대체하지 않습니다.
https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service 도 참조하십시오.
@Injectable()
export class NodeService {
private node:Subject<Node> = new BehaviorSubject<Node>([]);
get node$(){
return this.node.asObservable().filter(node => !!node);
}
addNode(data:Node) {
this.node.next(data);
}
}
@Component({
selector : 'node-display',
providers: [NodeService],
template : `
<router-outlet></router-outlet>
`
})
export class NodeDisplayComponent implements OnInit {
constructor(private nodeService:NodeService) {}
node: Node;
ngOnInit(): void {
this.nodeService.getNode(path)
.subscribe(
node => {
this.nodeService.addNode(node);
},
err => {
console.log(err);
}
);
}
}
export class ChildDisplay implements OnInit{
constructor(nodeService:NodeService) {
nodeService.node$.subscribe(n => this.node = n);
}
}
예, 라우터 출구 구성 요소에 직접 데이터를 전달할 수 있습니다.안타깝게도 다른 답변에서 언급한 것처럼 각 템플릿 바인딩을 사용하여 이 작업을 수행할 수 없습니다.당신은 타이프스크립트 파일에 데이터를 설정해야 합니다.관측 가능한 항목이 포함된 경우(아래 설명)에는 큰 경고가 있습니다.
방법:
라우터 콘센트에 연결합니다.activate
상위 템플릿의 이벤트:
<router-outlet (activate)="onOutletLoaded($event)"></router-outlet>
부모의 유형 스크립트 파일로 전환하고 활성화될 때마다 자식 구성 요소의 입력을 프로그래밍 방식으로 설정합니다.
onOutletLoaded(component) {
component.someProperty = 'someValue';
}
다 했어요.
위 러나위의버전은그▁of,▁however.onOutletLoaded
명확성을 위해 단순화됩니다.모든 하위 구성 요소가 할당하는 것과 정확히 동일한 입력을 갖도록 보장할 수 있는 경우에만 작동합니다.입력이 다른 성분이 있는 경우 유형 가드를 사용합니다.
onOutletLoaded(component: MyComponent1 | MyComponent2) {
if (component instanceof MyComponent1) {
component.someInput = 123;
} else if (component instanceof MyComponent2) {
component.anotherInput = 456;
}
}
왜 이 방법이 서비스 방법보다 선호될 수 있습니까?
이 방법과 서비스 방법 모두 하위 구성 요소와 통신하는 "올바른 방법"이 아니므로 프로젝트에 더 적합한 방법을 결정하면 됩니다.
그러나 이 방법은 "소통을 위한 서비스 만들기" 접근 방식(즉, 부모는 서비스를 필요로 하고 자녀는 모두 서비스를 필요로 하여 자녀를 다른 곳에서 사용할 수 없게 함)과 관련된 긴밀한 결합을 방지합니다.
대부분의 경우 이 방법은 @Inputs를 통해 하위 구성 요소에 데이터를 계속 전달할 수 있기 때문에 "각도 방식"에 더 가깝습니다.또한 서비스와 긴밀하게 결합하고 싶지 않거나 결합할 수 없는 기존 또는 타사 구성요소에도 적합합니다.
반면에, 그것은 덜 각진 방식처럼 느껴질 수도 있습니다.
주의사항
할 때 할 점은 파일에 되는 파이프 이을사때할예점주파스데형은일서전에때이를터패비파템기동턴프이사는되용에릿플기에달문하식크의할립트용)을 사용할 수 없다는 것입니다.{{ myObservable$ | async }}
를 클릭하여 를 사용하여 관찰 가능한 데이터를 자동으로 사용하고 하위 구성 요소로 전달합니다.
대신 다음과 같은 경우에는 항상 현재 관측 가능한 값을 가져오도록 설정해야 합니다.onOutletLoaded
함수가 호출됩니다.이를 위해서는 상위 구성 요소의 부품을 분해해야 할 수도 있습니다.onDestroy
기능. 일이 . 관찰 이 가 종종 .템플릿에 도달하지도 않는 관찰 가능 항목을 사용하는 경우와 같이 이 작업을 수행해야 하는 경우가 종종 있습니다.
귄터의 답변은 훌륭합니다. 저는 관찰 가능한 것을 사용하지 않고 다른 방법을 지적하고 싶습니다.
여기서 우리는 이러한 개체가 참조를 통해 전달된다는 것을 기억해야 합니다. 따라서 부모 개체에 영향을 미치지 않고 자식 개체에 대한 작업을 수행하려면 귄터의 솔루션을 사용하는 것이 좋습니다.하지만 그것이 문제가 되지 않거나 실제로 원하는 행동이라면, 저는 다음을 제안하고 싶습니다.
@Injectable()
export class SharedService {
sharedNode = {
// properties
};
}
부모에서 다음 값을 할당할 수 있습니다.
this.sharedService.sharedNode = this.node;
그리고 자녀(및 부모)의 경우 생성자에게 공유 서비스를 주입합니다.모듈의 모든 구성 요소에 대해 싱글톤 서비스를 원하는 경우 모듈 수준 공급자 어레이에서 서비스를 제공해야 합니다.또는 부모의 공급자 배열에만 서비스를 추가하면 부모와 자식이 동일한 서비스 인스턴스를 공유합니다.
node: Node;
ngOnInit() {
this.node = this.sharedService.sharedNode;
}
했듯이, 그고뉴친먼지절게적이듯했또한당신은, 이하리▁also▁have또한▁and▁can▁you,당,은신▁new▁pointedman.this.sharedService.sharedNode
HTML 템플릿 또는 getter에서:
get sharedNode(){
return this.sharedService.sharedNode;
}
상위에서 하위로 데이터를 전달하는 세 가지 방법이 있습니다.
- 공유 가능한 서비스를 통해: 자녀와 공유하고자 하는 데이터를 서비스에 저장해야 합니다.
다른 데이터를 수신해야 하는 경우 하위 라우터 해결 프로그램을 통해
this.data = this.route.snaphsot.data['dataFromResolver'];
상위 라우터 확인 프로그램을 통해 상위 라우터로부터 동일한 데이터를 수신해야 하는 경우
this.data = this.route.parent.snaphsot.data['dataFromResolver'];
참고 1: 여기에서 해결 프로그램에 대해 읽을 수 있습니다.또한 Resolver 및 Resolver를 모듈에 등록한 다음 Resolver에서 구성 요소로 데이터를 검색하는 방법의 예도 있습니다.확인자 등록은 부모 및 자식에서 동일합니다.
참고 2: 라우터에서 데이터를 가져올 수 있는 활성화된 경로에 대한 내용을 여기에서 읽을 수 있습니다.
서비스:
import {Injectable, EventEmitter} from "@angular/core";
@Injectable()
export class DataService {
onGetData: EventEmitter = new EventEmitter();
getData() {
this.http.post(...params).map(res => {
this.onGetData.emit(res.json());
})
}
구성 요소:
import {Component} from '@angular/core';
import {DataService} from "../services/data.service";
@Component()
export class MyComponent {
constructor(private DataService:DataService) {
this.DataService.onGetData.subscribe(res => {
(from service on .emit() )
})
}
//To send data to all subscribers from current component
sendData() {
this.DataService.onGetData.emit(--NEW DATA--);
}
}
이 질문에 이어 Angular 7.2에서는 기록 상태를 사용하여 부모에서 자식으로 데이터를 전달할 수 있습니다.그래서 당신은 다음과 같은 것을 할 수 있습니다.
보내기:
this.router.navigate(['action-selection'], { state: { example: 'bar' } });
검색:
constructor(private router: Router) { console.log(this.router.getCurrentNavigation().extras.state.example); }
하지만 일관성 있게 행동하도록 주의하세요.예를 들어, 라우터 배출구를 사용하여 왼쪽 사이드 막대에 목록을 표시하고 오른쪽에 선택한 항목의 세부 정보를 표시한다고 가정합니다.다음과 같은 것:
항목 1(x) | ...........................................................................................................
항목 2(x) | ......선택한 항목 세부 정보...
항목 3(x) | ...........................................................................
항목 4(x) | ...............................................................................................................................
이제 일부 항목을 이미 클릭했다고 가정합니다.브라우저 뒤로 버튼을 클릭하면 이전 항목의 세부 정보가 표시됩니다.하지만 그 동안 (x)를 클릭하고 목록에서 해당 항목을 삭제했다면 어떻게 하시겠습니까?그런 다음 뒤로 클릭하면 삭제된 항목의 세부 정보가 표시됩니다.
다른 방법이 있습니다.저는 제 방식이 많은 문제를 해결한다고 믿습니다.
이것이 경로를 처리하는 기본 방법입니다.
{ path: 'sample/page1', component: sampleComponent1 },
{ path: 'sample/page2', component: sampleComponent2 },
{ path: 'sample/page3', component: sampleComponent3 },
대신 아래와 같은 경로를 작성합니다.
{ path: 'sample/:sub', component: sampleComponent },
보다시피, 우리는 경로를 결합하고 경로 매개 변수를 만들었습니다.구성 요소에 대한 매개 변수 값을 수신할 수 있습니다.
// sampleComponents.ts :
sub = this.route.snapshot.params['sub'];
이제 해당 구성 요소의 HTML 파일에서 하위 구성 요소로 해당 페이지를 가져옵니다.그러면 우리는 그들에게 직접 데이터를 보낼 수 있습니다.
// sampleComponent.html :
<app-cmp-page1 *ngIf="sub==='page1'" [data]="data"></app-cmp-page1>
<app-cmp-page2 *ngIf="sub==='page2'" [data]="data"></app-cmp-page2>
<app-cmp-page3 *ngIf="sub==='page3'" [data]="data"></app-cmp-page3>
언급URL : https://stackoverflow.com/questions/41451375/passing-data-into-router-outlet-child-components
'sourcecode' 카테고리의 다른 글
Psql 모든 표 나열 (0) | 2023.05.03 |
---|---|
어레이별 MongoDB 그룹 내부 요소 (0) | 2023.05.03 |
Git/GitHub 기록에서 폴더 및 폴더 내용 제거 (0) | 2023.05.03 |
UI 보기의 왼쪽 상단 및 오른쪽 상단 모서리에만 모서리 반지름을 설정하는 방법은 무엇입니까? (0) | 2023.05.03 |
zip 아카이브에서 파일 하나를 업데이트하는 방법 (0) | 2023.05.03 |