在角度2中将更高的父组件(不是直接父组件)注入子组件

时间:2017-01-03 23:41:04

标签: angularjs angular

我需要注入一个不是直接父级的父组件。

@Host()装饰器允许只注入直接父组件。

真实示例 - 菜单和菜单项组件。我想在页面上放置菜单

<menu [name]="'smth'">
  <auth-logout></auth-logout>
  <!-- ... other menu items -->
</menu>

name通过菜单服务在菜单(e.x. toggle)上输入操作。 任何菜单项子组件都可以包含menu-item组件

<menu-item (itemClick)="logout()">
  LOGOUT
</menu-item>

menu-item模板

<div class="menu-item"    
     (click)="onClick()">
  <ng-content></ng-content>
</div>

plnkr http://plnkr.co/edit/ArQZYZsHQgn6I2eK3AZd

我想将menu组件注入menu-item,以便在close()点击事件上调用menu-item方法。 auth-logout不应该对这个菜单组件交互有任何了解,我也不想在每个菜单项中复制关闭逻辑。

为什么不这样包裹?

<menu>
  <menu-item>
    <auth-logout></auth-logout>
  </menu-item>
</menu>

因为menu-item块有一些样式会破坏正确点击子组件(ex padding),并且很难在点击时自动关闭菜单(需要将菜单名称传递给每个组件,如{{1或者在这个组件中添加输出)

为什么不使用来自auth-logout的服务电话? 因为它需要将菜单名称传递到每个菜单项(例如menu-item)并向下传递到auth-logout,但像menu-item这样的组件不应该知道有关此交互或菜单名称或其他任何内容的任何内容

还有一个例子 - 带有一些项目子组件的项目列表,它监听列表更改事件(列表组件中的主题)并通过添加新的时间戳参数来发出一些内容(ex item image auth-logout更新重置缓存和更新图像)。由于深层组件嵌套(由于页面上的不同列表需要名称),传递列表名称以通过服务进行交互太复杂了

这种情况在ng1中运行良好,src属性允许将任何更高级别的父级注入组件

更新

上面的示例可以通过删除require并在构造函数注入中添加遗漏@Host()来解决(thx @yurzui)。 但真正的问题更复杂,这个解决方案没有帮助。这是更新的plnkr。 http://plnkr.co/edit/p7Vd4FRpHPRtyEuL6pEZ

差异是添加了具有此模板的private组件

header-menu

<menu> <ng-content></ng-content> </menu> 注入menu组件不适用于此组件嵌套

menu-item

更新/答案: header-menu menu auth-logout menu-item 的最终案例属于这个问题github.com/angular/angular/issues/5126,这还不支持。

2 个答案:

答案 0 :(得分:3)

只需删除@Host()装饰,不要忘记private。否则,this.menuComponent将始终为undefined而不进行private修改。

constructor (@Optional() private menuComponent: MenuComponent)

<强> Plunker Example

答案 1 :(得分:0)

此处修改了plunkr 这是传递实例的一种方法:使用Template reference variables
注射对我来说太复杂了。

在app.component.html中:

<menu #mm><!-- use whatever name after # -->
  <auth-logout [menu]='mm'></auth-logout>
</menu>

在auth-logout.component.html中:

<menu-item (itemClick)="logout()" [menu]="menu">
  LOGOUT
</menu-item>

在auth-logout.component.ts中:

@Input() menu: MenuComponent;

在menu-item.component.ts中:

@Input() menu: MenuComponent;

#mm(MenuComponent的实例)将作为menu向下传递到auth-logout,然后向下传递到菜单项menu,然后您可以调用{{菜单项中的1}}。