Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 choose template dynamically according to service response

I have a component called "Node" which should display a single post, but I have more than a post type and each type has its own view (layout).

So this component has an ID parameter which will be used to get a post response from a service then according to post type it should display the correct layout.

ex: localhost/test_app/node/123 where 123 is the id parameter.

Approach 1: using ngIf in the tamplate

@Component({
  selector: 'node',
  directives: [Post, Project],
  template: `
    <post *ngIf="response.post.post_type == 'post'" content="response.post"></post>
    <project *ngIf="response.post.post_type == 'project'" content="response.post"></project>
  `,
})

export class Node{

  id: number;
  response: any;
  constructor(private _param: RouteParams,
              public service: Service
  ){
    this.id = +_param.get('id');
  }

  ngOnInit(){
    this.service.get(this.id).subscribe(
      res=> this.response = res.json()
    );
  }

}

Approach 2: using dynamic component loader.

@Component({
  selector: 'node',
  directives: [Post, Project],
  template: '<div #container></div>'
})

export class Node{

  id: number;
  response: any;

  constructor(private _param: RouteParams,
              public service: Service,
              private loader:DynamicComponentLoader,
              private elementRef:ElementRef
  ){
    this.id = +_param.get('id');
  }

  ngOnInit(){
    this.service.get(this.id).subscribe(
      res=> {
          this.response = res.json();
          this.renderTemplate();
      }
    );
  }

  renderTemplate(template) {
    this.loader.loadIntoLocation(
      this.getCorrectTemplate(),
      this.elementRef,
      'container'
    )
  }

  getCorrectTemplate(){
    if(this.response.post.post_type == "post"){
        return '<post content="response.post"></post>';
    }
    else{
        return '<project content="response.post"></project>';
    }
  }

}

I'm wondering which approach is more efficient or if there is a better approach, please share it.

like image 341
Murhaf Sousli Avatar asked Jun 06 '16 04:06

Murhaf Sousli


1 Answers

If you have a limited set of possible templates then *ngIf or *ngSwitch is a good approach. It allows you to use [] and () bindings between parent and child.

If you have a set of templates that are statically unknown and for example provided by a parameter then *ngIf doesn't work. Then ViewContainerRef.createComponent() (replaces DynamicComponentLoader) is the right approach. For an example see Angular 2 dynamic tabs with user-click chosen components

like image 184
Günter Zöchbauer Avatar answered Oct 20 '22 11:10

Günter Zöchbauer