如何实现嵌套的二级路由并仍然从子级获取数据?角 6 [英] How to implement nested secondary routing and still get the data from child? Angular 6

查看:29
本文介绍了如何实现嵌套的二级路由并仍然从子级获取数据?角 6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是将数据从路由的子级发送到父级.我想从子级获取变量的引用,该变量通过辅助路由嵌套在子级中到父级,以便变量同步到父级.这个变量最终将是表单验证状态的布尔值.不幸的是,当我使用 Behavior Subject 时,我认为我必须使用组件选择器,它似乎不能很好地与我的应用程序中的路由配合使用.

这是来自应用程序模板的示例...当我添加 app-new-user 组件选择器时,它似乎搞砸了名为 router outlet 的 newuserinput :(

<路由器插座></路由器插座><!-- <router-outlet name="newuserinput" (newUserInfoCompleteEvent)="receiveNewUserInfoComplete($event)"></router-outlet>--><router-outlet (activate)='getVState($event);' name="newuserinput"></router-outlet><router-outlet name="newuserorginfo"></router-outlet><router-outlet name="newusersupervisorinfo"></router-outlet><router-outlet name="newusersecurityinfo"></router-outlet><!-- 结束--><!-- 对于 ViewChild:从 child 中获取表单有效性状态 --><!-- <app-new-user-input style="display:none;"></app-new-user-input>--><!-- 不能这样做,因为将子组件选择器放在父组件中会禁用子路由器出口 -->

在我准备的stackblitz原型中,子/父结构是成功地与服务合作以显示所需的信息;然而,一旦我用命名路由(就像我上面提供的应用程序的代码片段)替换父(app-component)中的组件选择器,这就会中断.我对这个原型的目标是在父级上显示来自次要孩子的你好",二级路由参数正确显示在地址栏中,如下所示:https://behavior-subject-0007.stackblitz.io/(child:child/(secondarychild:secondarychild))

我的问题:那么,我如何实现嵌套的二级路由并仍然通过从子级到父级的引用获取数据,以便地址栏显示如下 https://behavior-subject-0007.stackblitz.io/(child:child/(secondarychild:secondarychild))?

我可以为此使用行为主题还是有更好的方法?我正在考虑尝试实施 AJ2_82 的解决方案.

我还通过使用组件主机元数据研究了路由子组件上的简单属性绑定...

我对编程比较陌生,所以可能有一个显而易见"的解决方案,感谢您提供的任何帮助.

如果你分享你的方式来满足相同的要求(命名路由器出口地址和从孩子到父母的参考数据),我全神贯注.谢谢.

解决方案

一个从众多渠道解决的问题是使用 events ,将事件发射器加载到您的共享服务 public onChange: EventEmitter= new EventEmitter(); 然后将它从父级广播到它的子级,或者相反,像这样

changeMes​​sage(message: string) {this.currentMessage = of(message)this.onChange.emit(消息);}

在每次需要的组件加入通信配置单元时,从该服务添加一个事件捕获器:this.myService.onChange.subscribe(message=> this.message = message);

通过这种方式,您可以实现一种向外"但功能齐全的方法,以在路由之间实时共享数据.

查看此示例.或者你可以看到这个稍微不同的实现合并兄弟组件和路由.

<小时>

或者你可以使用特殊的路由参数

通过这种方式,您将不允许来自另一个共存层次结构的任何外部组件干扰在定义的路由模块之间交换的这些内部消息,因为您在它们之间进行了不正当的传递.

您可以这样配置模块:

导出常量路由:Routes = [{ path: '', redirectTo: 'component-one/:message', pathMatch: 'full' },{ path: 'component-one/:message', 组件: ComponentOne },{路径:'组件二/:消息',组件:组件二,孩子们: [{ path: '', redirectTo: 'child-one', pathMatch: 'full' },{ path: 'child-one/:message', 组件: ChildOne },{ 路径:'child-two/:message',组件:ChildTwo }]}];

这样,每次调用这些关联之一都会伴随一些参数,以便在其组件 html 核心中使用.

在下面的示例中,我将函数调用中的参数设为可选,以判断它是否由组件加载触发,从而重新生成,但它源自按钮单击,因此分别更新为一些自定义部分.

newMessage(param?) {if(typeof(param) === '未定义')this.message = "家长";别的this.message = 参数;var actualroute=this.router.routerState.snapshot._root.children[0].children[0].value.url[0].path;this.router.navigate(['/component-two', this.message , actualroute, this.message ],{relativeTo: this.route});}

您可以在这里看到一切正常运行

一>.谢谢你的这个有趣的挑战.

弱点:每次更新变量 message 时,路由器都会再次导航到相同的层次结构,这会花费时间,尤其是对于更大的实现.>

强点:当您调用 router.navigate 时,可以在组件之间传递自定义数据,例如对子项说mesage1",对子项说message2"一行父级:this.router.navigate(['/component-two', 'message2', 'child-one', 'message1']);.这可以通过使用服务来完成,但非常复杂且与条件纠缠不清.

My goal is to send data from a routed child to the parent. I want to get the reference of a variable from the child, which is nested within a child to the parent through secondary routes so that the variable is synced to the parent. This variable will eventually be the boolean of a form validation state. Unfortunately, when I use Behavior Subject I think I have to use the component selector which seems not to play nicely with the routes in my application.

This is a sample from the template of the application... It seems when I add the app-new-user component selector it screws up the newuserinput named router outlet :(

<!-- To BLADE LAYER 3 -->
<router-outlet></router-outlet>
<!-- <router-outlet name="newuserinput" (newUserInfoCompleteEvent)="receiveNewUserInfoComplete($event)"></router-outlet> -->
<router-outlet (activate)='getVState($event); ' name="newuserinput"></router-outlet>
<router-outlet name="newuserorginfo"></router-outlet>
<router-outlet name="newusersupervisorinfo"></router-outlet>
<router-outlet name="newusersecurityinfo"></router-outlet>
<!-- end -->



<!-- For ViewChild: bringing form validity state from child -->
<!-- <app-new-user-input style="display:none;"></app-new-user-input> -->
<!-- can't do this because putting the child component selector in the parent disables the childs router outlet -->

In mystackblitz prototype that I have prepared, the child/parent structure is successfully working with the service to display the desired information; however, as soon as I replace the component selectors in the parent(app-component) with named routes (like in the snippet of my application that I provided above) this breaks. My goal for this prototype is to display 'Hello from secondary child' on the parent with the secondary routing route params being properly displayed in the address bar like this: https://behavior-subject-0007.stackblitz.io/(child:child/(secondarychild:secondarychild))

My question: So, how do I implement nested secondary routing and still get the data by reference from child to parent so that the address bar displays like this https://behavior-subject-0007.stackblitz.io/(child:child/(secondarychild:secondarychild))?

Can I use Behavior Subject for this or is there a better way? I was thinking about trying to implement AJ2_82's solution.

I was also looking into simple property binding on the routed child component by using the components host metadata...

I'm relatively new to programming so there could be an 'obvious' solution, thanks for any help you can provide.

If you share YOUR way that would satisfy the same requirements (named router outlet address and data by reference from child to parent) I am all ears. Thank you.

解决方案

One from many outlets to the problem is to use events , load an event emitter to your shared service public onChange: EventEmitter<string> = new EventEmitter<string>(); then brodcast it from the parent to its children, or counterwise, like this

changeMessage(message: string) {
    this.currentMessage = of(message)
    this.onChange.emit(message); 
  }

In each occurence when a desired component you want it to join the communicative hive, add an event catcher from this service: this.myService.onChange.subscribe(message=> this.message = message);

This way you could implement an "outward" but complete functional approach to share data at real time between routes.

see this sample. Or you can see this slightly different implementation that merges sibling components and routes.


Or you can use idiosyncratic route parameters

By this way you wouldn't allow any foreign component from another coexistant hierarchy to interfer in these inner messages exchanged between a defined module of routes, because you are underhandedly passing them inbetween.

You would configure the module this way:

export const routes: Routes = [
  { path: '', redirectTo: 'component-one/:message', pathMatch: 'full' },
  { path: 'component-one/:message', component: ComponentOne },
  { path: 'component-two/:message', component: ComponentTwo,
    children: [
      { path: '', redirectTo: 'child-one', pathMatch: 'full' },
      { path: 'child-one/:message', component: ChildOne },
      { path: 'child-two/:message', component: ChildTwo }
    ]
  }
];

So that each call to one of those filiations accompanies some parameter to be used in the component html core of which.

In the following example, I made the parameter in function call optional to tell if it was triggered from a component load, thus regenerated, neverthless it originates from a button click, hence just updated respectively to some custom parts.

newMessage(param?) {

    if(typeof(param) === 'undefined')
       this.message = "Parent";
    else
       this.message = param;

    var actualroute=this.router.routerState.snapshot._root.children[0].children[0].value.url[0].path;
    this.router.navigate(['/component-two', this.message , actualroute, this.message  ],{relativeTo: this.route});   
}

You can see it all working here. Thank you for this fun-challenge.

Weak spot: At each update of the variable message, the router proceeds to navigate all over again to the same hierarchy which costs time especially for bigger implementations.

Strong point: When you call a router.navigate there is ability to pass custom data between components, say 'mesage1' for a child and 'message2' for a parent in one row: this.router.navigate(['/component-two', 'message2' , 'child-one', 'message1']);. This can be done but very complicatedly and condition-entangledly using a service.

这篇关于如何实现嵌套的二级路由并仍然从子级获取数据?角 6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆