I have a recursive structure that's composed of two components:
- OptionsMenuComponent (A menu)
- MenuItemComponent (The menu items)
OptionsMenuComponent: (Template + Component)
Template:
<menu-item *ngFor="let menuItem of menu.menuItems" [menuItem]="menuItem"> </menu-item>
Component:
import { Component, Input } from '@angular/core';
import { Menu } from '../models/menu.model';
import { MenuItemComponent } from '../menu-item/menu-item.component';
@Component({
moduleId: __moduleName,
selector: 'options-menu',
templateUrl: 'options-menu.component.html',
styleUrls: ['options-menu.component.css'],
directives: [MenuItemComponent],
})
export class OptionsMenuComponent {
@Input() menu: Menu;
constructor() { }
}
Menu Item: (Template + Component)
Template:
<span class="menu-item-title">{{menuItem.title}}</span>
<options-menu *ngIf="menuItem.subMenu != null" [menu]="menuItem.subMenu" class="sub-menu"> </options-menu>
Component:
import { Component, Input, forwardRef } from '@angular/core';
import { MenuItem } from '../models/menu-item.model';
import { OptionsMenuComponent } from '../options-menu/options-menu.component';
@Component({
moduleId: __moduleName,
selector: 'menu-item',
directives: [forwardRef(() => OptionsMenuComponent)],
templateUrl: 'menu-item.component.html',
styleUrls: ['menu-item.component.css'],
})
export class MenuItemComponent {
@Input() menuItem: MenuItem;
constructor() { }
}
Note: I removed almost all logic and design to simplify as it's not relevant
As you can see the OptionsMenuComponent knows the MenuItemComponent and the other way around.
In addition you might have noticed that in MenuItemComponent I used forwardRef inside the directive. Without that when I load the page I get the following error:
Error: Uncaught (in promise): Unexpected directive value 'undefined' on the View of component 'MenuItemComponent'
Currently the way it's written (with forwardRef) it works great but TSLint is unhappy with it and outputs the following:
[gulp-tslint] error (no-forward-ref) menu-item.component.ts[9, 18]: Avoid using forwardRef in class "MenuItemComponent"
I looked around the web for alternative solutions and came up empty handed. All I could find is two suggestions:
- My solution with the forwardRef
- "You have a cyclic reference, you're doing something wrong so decouple them" (not exact words)
The first suggestion works but my question is if it's possible to avoid this because it doesn't sound like good practice (And everywhere people say to avoid it)
The second suggestion is correct and easy to implement for most cases but how do I do that in a recursive structure (using angular2 components)?
Thanks ahead,
p.s - before this I had all the functionality in one component and I didn't have any problem with that single component referencing itself (no need for forwardRef) so please don't recommend doing so because it's not the case here (trying to keep the components small and simple)
TL;DR:
Two components referencing each other (recursive structure was required).
Without using forwardRef I get error, Is there an alternative solution that doesn't involve using forwardRef?