0

Is it possible to do an ngFor on Components listed in a feature module's declarations? They all have a few things in common such as title, settings actions, view all, but otherwise the components each do very different things, display different data etc. Does anybody know of a way to best accomplish this?

kittycatbytes
  • 995
  • 8
  • 14
  • welcome to SO. read [**asking help**](http://stackoverflow.com/help/how-to-ask) before asking a question. Revise your post with relevant code snippets to help – Aravind May 12 '17 at 20:48
  • I've been on here for two years and I never want to ask questions because of stuff like this. I can't comment or vote or anything. I joined like 2 years ago. I'm asking a simple question: how do you access a feature module's declarations? I don't understand why that would require code snippets. – kittycatbytes May 12 '17 at 21:06
  • we dont entertain questions like these with out codes or opinions etc. It doesn't matter if you are here for 2 years or 20 years. But stick to basics. – Aravind May 12 '17 at 21:07
  • 1
    Hi kittycatbytes. Yes, I've been disappointed that SO isn't a little more friendly ... especially to newbies. But @Aravid's comment is definitely kinder than most. I often see a negative vote with no reason ... which must be really frustrating. Anyway, can you provide more information on what you are trying to accomplish? You don't want to list the set of components in your declarations and want to somehow build them with an ngFor instead? – DeborahK May 12 '17 at 21:25
  • @kittycatbytes Look into this [**example**](http://stackoverflow.com/questions/42728389/angular2-viewwrappederror-on-component-2-when-object-deleted-from-component-1/42728612#42728612) for your question – Aravind May 13 '17 at 02:40
  • @DeborahK yes, actually this is what I ended up doing - I did a bit more research and found a link to help me solve my problem. I'm working on writing up the solution I used below – kittycatbytes May 15 '17 at 13:50

2 Answers2

2

I found the following solution that I repurposed to use with my own code. Please review and lmk what you think.

Home Module:

export const routes: Routes = [
    { path: '', component: HomePageComponent }
];

@NgModule({
    imports: [CommonModule,
        RouterModule.forChild(routes),
        MdGridListModule,
        MdCardModule,
        MdIconModule,
        MdButtonModule
    ],
    declarations: [
        HomePageComponent,
        HomeDashboardComponent,
        HomeGizmoComponent,
        HighlightsComponent,
        LawsregComponent,
        NewsComponent,
        StarComponent,
        TracComponent,
        BudgetComponent,
        The12gComponent
    ],
    entryComponents: [
        HighlightsComponent,
        LawsregComponent,
        NewsComponent,
        StarComponent,
        TracComponent,
        BudgetComponent,
        The12gComponent
    ],
    providers: []
})
export class HomeModule { }

Home Component:

@Component({
  selector: 'home',
  template: `<home-dashboard [gizmos]="types"></home-dashboard>`
})
export class HomePageComponent {
    types = [
        HighlightsComponent,
        LawsregComponent,
        NewsComponent,
        StarComponent,
        TracComponent,
        BudgetComponent,
        The12gComponent
    ];



  constructor(title: Title) {
      title.setTitle('Home');

  }


}

Home Dashboard Component:

@Component({
  selector: 'home-dashboard',
  template: `
    <md-grid-list cols="3" gutterSize="1rem" >
  <md-grid-tile *ngFor="let gizmo of gizmos">
    <md-card><home-gizmo-component [type]="gizmo"></home-gizmo-component></md-card>
  </md-grid-tile>
</md-grid-list>

`
})
export class HomeDashboardComponent {
    @Input() gizmos;

  constructor() {

  }
}

Home Gizmo Component:

@Component({
  selector: 'home-gizmo-component',
  template: ` <div #target></div>`
})
export class HomeGizmoComponent {
    @ViewChild('target', { read: ViewContainerRef }) target: ViewContainerRef;
    @Input() type: Type<Component>;
    cmpRef: ComponentRef<Component>;
    private isViewInitialized: boolean = false;

    constructor(private componentFactoryResolver: ComponentFactoryResolver, private compiler: Compiler) { }

    updateComponent() {
        if (!this.isViewInitialized) {
            return;
        }
        if (this.cmpRef) {
            // when the `type` input changes we destroy a previously 
            // created component before creating the new one
            this.cmpRef.destroy();
        }

        let factory = this.componentFactoryResolver.resolveComponentFactory(this.type);
        this.cmpRef = this.target.createComponent(factory)
        // to access the created instance use
        // this.compRef.instance.someProperty = 'someValue';
        // this.compRef.instance.someOutput.subscribe(val => doSomething());
    }

    ngOnChanges() {
        this.updateComponent();
    }

    ngAfterViewInit() {
        this.isViewInitialized = true;
        this.updateComponent();
    }

    ngOnDestroy() {
        if (this.cmpRef) {
            this.cmpRef.destroy();
        }
    }
}
Community
  • 1
  • 1
kittycatbytes
  • 995
  • 8
  • 14
1

You could write a parent class component and have child components inherit from the parent using extend.

Base component:

@Component({
  selector : 'my-base',
  template: `
    <div>
      Am I the base component: {{isBase}}?
    </div>
  `
})
export class BaseComponent {
  @Input() isBase: boolean = true;
}

Child component:

@Component({
  selector : 'my-inherited',
  template: `
    <div>
      I'm def not the {{isBase}}!
    </div>
  `
})
export class InheritedComponent extends BaseComponent {}

In use:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <my-base></my-base>
      <hr />
      <my-inherited [isBase]="false"></my-inherited>
    </div>
  `
})
export class App { }
Yeysides
  • 1,262
  • 1
  • 17
  • 27
  • Interesting - thank you for this...perhaps I should redo my code to do the above. I found another solution that also works, I'm about to post below - please let me know if you think the solution is inferior to the above after I post plz. – kittycatbytes May 15 '17 at 13:52