4

I wanted to load component templateUrl based on value passed from parent component. I know tt can be pass through property binding to component by have @Input, I gave example below in which myHtml will be passed as templateName.

.But there is no ability to access @Input value inside templateUrl function. I think templateUrl is the first thing going to evaluate by asking for HTML, after that all other component code gets executed.

Like in angular 1 has ability to pass some value from attribute, & then I can use that value inside templateUrl function as a parameter like below.

templateUrl: function(element, attrs){
    //was getting value
    return '/app/templates/'+ attrs.myTemplateName + '.html'
}

But same thing I can't do in Angular2, as templateUrl is strongly typed as string so it doesn't take function as an attribute.

Is there a way to achieve this OR I missed something simple?

Edit

I've already looked at this answer which isn't what I want. In referred answer, it render DOM using DynamicComponentLoader which loads another component.

This is not what I wanted, because creating new separate component for having different templateUrl doesn't make sense in mine case.

Any idea how do I implement this?

5
  • @MarkRajcok The way I has been done in marked as duplicate answer, created template manually/assign independant component. And don't wanted to create a new component having different templateUrl, it sounds repeatative to me.. please guide me If I still missed something.. Commented Mar 17, 2016 at 21:08
  • 1
    Dynamic templateUrls are not supported, according to the answers to the other question (that's why I originally closed this one). If you want a dynamic template, I believe you have to use DynamicComponentLoader. It seems like you're trying to create a generic component of sorts, which can have many different possible templates. That sounds like a job for a DynamicComponent loader, doesn't it? Commented Mar 17, 2016 at 22:01
  • See stackoverflow.com/questions/36008476/… Commented Mar 18, 2016 at 5:41
  • @MarkRajcok correct, this seems kind of workaround, but that need to have boilerplate code, though thanks for explanation. But in linked answer I saw that for each templateUrl I need to create a separate FakeComponent for having different templateUrl, so for 3 templateUrl's, I need to create three FakeComponent, which isn't sounds good for me(unwanted boilerplate code). I think should be a better way than this. am I thinking in wrong direction? Commented Mar 18, 2016 at 5:41
  • 1
    @AngelAngel thanks..the suggested answer over the referred link, I already tried that thing before adding question.. Angular2 doesn't have such option to have function for templateUrl, because @Component metadata templateUrl property is strongly typed as string, I already mentioned the thing in my question. Thanks :-) Commented Mar 18, 2016 at 7:57

1 Answer 1

3

Been struggling with something similar, but unfortunately you can't do this. Component templates are compiled at runtime. So, basically, I would make a component that compiles other child components (which I actually did)

DynamicComponentLoader is beign deprecated. You need to use the ComponentResolver class to load other components inside the main one, like so:

function makeComponent( selector, template, ...more )
{
  @Component({ selector: selector, template: template })
  class FakeComponent {}
  return FakeComponent;
}

@Component({ ... })
export class MainCmp implements OnInit
{
  // place to insert
  @ViewChild('viewChild', {read: ViewContainerRef}) viewChild: ViewContainerRef;

  constructor(private compiler: ComponentResolver){}
  // or OnChanges, or event binding.. should work

  ngOnInit()
  {
    // decide on your custom logic here, get you @Input, whatever...

    // and you can actually make some custom dynamic component...
    let childCmp = makeComponent( custom, stuff, here );

    // compile then insert in your location, defined by viewChild
    this.compiler.resolveComponent( childCmp )
      .then( (compFactory:ComponentFactory) => this.viewChild.createComponent(compFactory) )
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Looks like angular 2 does not support anymore this option??
keeping up to date with new changes in angular2, maybe this link can help: angular.io/docs/ts/latest/cookbook/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.