Angular 4:如何使用与parent和child相同的组件?
Angular 4: How to use same component as both parent and child?
我的要求是拥有 forms.In 树 parent 表单,单击按钮时仅会创建 child 表单。它可以继续这样直到 n-levels。
我的做法:
我创建了一个组件。这被用作 parent 和 child。单击按钮,我将项目动态添加到 ActivatedRoute 的 route.routeConfig.children。然后导航到相对于当前路径的添加路径。直到这一部分一切顺利。
所以我在屏幕上看到了所有表格。我只想让活动表单在屏幕上可见。然后单击一个按钮(后退按钮)我想转到它的 relaive parent 并仅显示该表单。通过在模板中使用 *ngif,我可以在打开 child 表单时隐藏 parent 表单。但是从 rm child 返回时无法使其可见。下面是我的代码。请让我知道我是否应该采取任何其他方法,或者我需要添加什么才能使其按我的方式工作。
我的组件。
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
providers: [ConfigService]
})
export class TestComponent implements OnInit, OnDestroy {
name: string;
age: Number;
showParent: boolean = true;
childrenRoute: Routes;
message: any;
subscription: Subscription;
private sub: any;
constructor(private router: Router, private route: ActivatedRoute, private _configService: ConfigService) {
this.name = 'test data';
this.age = 20;
this.router = router;
if(this._configService.getConfig('showParent') != null){
this.showParent=false;
}
this.subscription = router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
if (_configService.getConfig('showParent') != null) {
this.showParent = _configService.getConfig('showParent');
}
}
});
}
ngOnInit() {
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
showChildRecord() {
this.childrenRoute = [{
path: 'child',
component: TestComponent
}];
if (this.route.routeConfig != undefined) {
this.route.routeConfig.children = this.childrenRoute;
}
this._configService.setOption('showParent', false);
this.router.navigate(['./child'], { relativeTo: this.route });
}
back() {
this._configService.setOption('showParent', true);
this.router.navigate(["../"], { relativeTo: this.route });
}
}
我尝试使用服务在同一组件的每个实例之间共享数据。
@Injectable()
export class ConfigService {
private config = {};
setOption(option, value) {
this.config[option] = value;
}
getConfig(option: string) {
if(option != undefined){
return this.config[option] != undefined ? this.config[option]: null;
}else
return null;
}
}
模板test.component.html
<div *ngIf="showParent">
<p>Name:
<input type="text" [(ngModel)]="name">
</p>
<p>Age:
<input type="text" [(ngModel)]="age">
</p>
{{name}} : {{age}}
<button (click)="showChildRecord();" > Go to Child Record</button>
<button (click)="back();">Back</button>
</div>
<router-outlet></router-outlet>
App.module.ts 航线:
const appRoutes: Routes = [
{
path: 'child',
component: TestComponent,
children: [
{ path: 'child',
component: TestComponent
}
]
}
];
我正在尝试将 "showParent" 信息存储在服务中并根据操作切换它。在路由事件 "NavigationEnd" 下,我正在读取它并将其分配给 showParent propery.But 它不起作用。我的 parent 表单仍然被隐藏。我只看到空白屏幕。我注意到的一个问题是 "NavigationEnd" 事件被多次触发,可能是因为我使用的是同一组件,当创建新的 child 时,它会添加另一个事件。
我花了一些时间找到了上述问题的解决方案。于是想到这里分享。
所以有一些错误,也有一些学习。
我的方法有误:
- 我在 testComponent 下添加了 serive ConfigService。要在所有 child 组件之间共享相同的服务,我应该在根组件下添加该服务。否则每个组件都有自己的服务实例,数据也会不同。
表示
providers: [ConfigService]
应添加到 AppModule。
- 因为它只是一个服务,所以它不监听值的变化。所以我应该让它成为可观察的。
所以我没有使用上面的服务,而是创建了另一个服务,如下所示。
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: any) {debugger
this.subject.next(message);
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
在我订阅的 testComponent 中。我只添加更改的部分。因此,当我们导航回 parent 路由 ngOnDestroy of child 获取 called.Here 时,我们正在使用稍后在订阅中捕获的服务更改值parent 的回调。
constructor(private router: Router, private route: ActivatedRoute, private _configService: ConfigService,private _msgService:MessageService) {
this.name = 'test data';
this.age = 20;
this.router = router;
this.subscription = this._msgService.getMessage().subscribe(message => {
if(message['showParent']){
this.showParent=true;
}
});
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this._msgService.sendMessage({ 'showParent':true });
this.subscription.unsubscribe();
}
以上内容解决了 child 通知 parent 的问题。但就我而言,因为我可以进入多个级别。 单击最后一个 children 的后退 按钮会触发每个 parent 组件的订阅回调,直到第一个组件。所以每个 parent 组件都变得可见,而不仅仅是直接的 parent。虽然它没有解决我的目的,但我学会了这种跨 components.May 传输数据的方式,因为我可以使用路由路径之类的东西来决定它是否是即时的 parent。我还没搞定。
但我必须使用另一种简单的方法来解决我的问题。
方法二:
在模板下,我为 deactivate 添加了事件侦听器。
<router-outlet (deactivate)='onDeactivateChild($event)' ></router-outlet>
作为 TestComponent 的一部分,我添加了以下方法。
onDeactivateChild(){
this.showParent=true;
}
问题已解决。单击 child 的后退按钮 deactivate 事件被触发,parent 开始了解它。希望它能帮助面临这个问题的人。
谢谢。
我的要求是拥有 forms.In 树 parent 表单,单击按钮时仅会创建 child 表单。它可以继续这样直到 n-levels。
我的做法:
我创建了一个组件。这被用作 parent 和 child。单击按钮,我将项目动态添加到 ActivatedRoute 的 route.routeConfig.children。然后导航到相对于当前路径的添加路径。直到这一部分一切顺利。 所以我在屏幕上看到了所有表格。我只想让活动表单在屏幕上可见。然后单击一个按钮(后退按钮)我想转到它的 relaive parent 并仅显示该表单。通过在模板中使用 *ngif,我可以在打开 child 表单时隐藏 parent 表单。但是从 rm child 返回时无法使其可见。下面是我的代码。请让我知道我是否应该采取任何其他方法,或者我需要添加什么才能使其按我的方式工作。
我的组件。
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
providers: [ConfigService]
})
export class TestComponent implements OnInit, OnDestroy {
name: string;
age: Number;
showParent: boolean = true;
childrenRoute: Routes;
message: any;
subscription: Subscription;
private sub: any;
constructor(private router: Router, private route: ActivatedRoute, private _configService: ConfigService) {
this.name = 'test data';
this.age = 20;
this.router = router;
if(this._configService.getConfig('showParent') != null){
this.showParent=false;
}
this.subscription = router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
if (_configService.getConfig('showParent') != null) {
this.showParent = _configService.getConfig('showParent');
}
}
});
}
ngOnInit() {
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
showChildRecord() {
this.childrenRoute = [{
path: 'child',
component: TestComponent
}];
if (this.route.routeConfig != undefined) {
this.route.routeConfig.children = this.childrenRoute;
}
this._configService.setOption('showParent', false);
this.router.navigate(['./child'], { relativeTo: this.route });
}
back() {
this._configService.setOption('showParent', true);
this.router.navigate(["../"], { relativeTo: this.route });
}
}
我尝试使用服务在同一组件的每个实例之间共享数据。
@Injectable()
export class ConfigService {
private config = {};
setOption(option, value) {
this.config[option] = value;
}
getConfig(option: string) {
if(option != undefined){
return this.config[option] != undefined ? this.config[option]: null;
}else
return null;
}
}
模板test.component.html
<div *ngIf="showParent">
<p>Name:
<input type="text" [(ngModel)]="name">
</p>
<p>Age:
<input type="text" [(ngModel)]="age">
</p>
{{name}} : {{age}}
<button (click)="showChildRecord();" > Go to Child Record</button>
<button (click)="back();">Back</button>
</div>
<router-outlet></router-outlet>
App.module.ts 航线:
const appRoutes: Routes = [
{
path: 'child',
component: TestComponent,
children: [
{ path: 'child',
component: TestComponent
}
]
}
];
我正在尝试将 "showParent" 信息存储在服务中并根据操作切换它。在路由事件 "NavigationEnd" 下,我正在读取它并将其分配给 showParent propery.But 它不起作用。我的 parent 表单仍然被隐藏。我只看到空白屏幕。我注意到的一个问题是 "NavigationEnd" 事件被多次触发,可能是因为我使用的是同一组件,当创建新的 child 时,它会添加另一个事件。
我花了一些时间找到了上述问题的解决方案。于是想到这里分享。
所以有一些错误,也有一些学习。
我的方法有误:
- 我在 testComponent 下添加了 serive ConfigService。要在所有 child 组件之间共享相同的服务,我应该在根组件下添加该服务。否则每个组件都有自己的服务实例,数据也会不同。
表示
providers: [ConfigService]
应添加到 AppModule。
- 因为它只是一个服务,所以它不监听值的变化。所以我应该让它成为可观察的。
所以我没有使用上面的服务,而是创建了另一个服务,如下所示。
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: any) {debugger
this.subject.next(message);
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
在我订阅的 testComponent 中。我只添加更改的部分。因此,当我们导航回 parent 路由 ngOnDestroy of child 获取 called.Here 时,我们正在使用稍后在订阅中捕获的服务更改值parent 的回调。
constructor(private router: Router, private route: ActivatedRoute, private _configService: ConfigService,private _msgService:MessageService) {
this.name = 'test data';
this.age = 20;
this.router = router;
this.subscription = this._msgService.getMessage().subscribe(message => {
if(message['showParent']){
this.showParent=true;
}
});
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this._msgService.sendMessage({ 'showParent':true });
this.subscription.unsubscribe();
}
以上内容解决了 child 通知 parent 的问题。但就我而言,因为我可以进入多个级别。 单击最后一个 children 的后退 按钮会触发每个 parent 组件的订阅回调,直到第一个组件。所以每个 parent 组件都变得可见,而不仅仅是直接的 parent。虽然它没有解决我的目的,但我学会了这种跨 components.May 传输数据的方式,因为我可以使用路由路径之类的东西来决定它是否是即时的 parent。我还没搞定。
但我必须使用另一种简单的方法来解决我的问题。
方法二:
在模板下,我为 deactivate 添加了事件侦听器。
<router-outlet (deactivate)='onDeactivateChild($event)' ></router-outlet>
作为 TestComponent 的一部分,我添加了以下方法。
onDeactivateChild(){
this.showParent=true;
}
问题已解决。单击 child 的后退按钮 deactivate 事件被触发,parent 开始了解它。希望它能帮助面临这个问题的人。
谢谢。