Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
86 views
in Technique[技术] by (71.8m points)

javascript - Dynamic template URLs in Angular 2

I've been playing around with Angular 2 for the past few days and wondered if it was possible to provide a dynamic templateUrl to the @View decorator.

I have tried passing it a function and returning a string form it but the entire function just get's turned into a string.

I haven't really used Angular 1.x before either so I don't know if I'm just going about this in the wrong way, but is this possible, or is there a better way to create dynamic views?

For example I might want to display a form if the user is not logged in, but display a text message if they are logged in.

Something like this doesn't work:

@Component({
  selector: 'my-component'
})
@View({
  // This doesn't work
  templateUrl: function() {
    return this.isLoggedIn ? 'logged-in.html' : 'logged-out.html';
  }
})
class MyComponent {
  constructor() {
    this.loggedIn = false;
  }
}

Any help would be appreciated.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Although maybe not the most elegant solution, I used the DynamicComponentLoader and ElementRef to dynamically assign template value to a component. In fact, I was looking for a solution where I can add multiple custom components into a placeholder.

I tried service injection in the function as outlined by shmck this doesn't work as the services are not available yet when the template function is called. Indeed, this refers to the Window object.

Reference URLs for the solution I used are to be found on: create dynamic anchorName/Components with ComponentResolver and ngFor in Angular2

I also refer this way to Plnkr1 and Plnkr2.

The site Dartdocs provides nice documentation on Angular 2 DynamicComponentLoader class, also applicable to TypeScript.

In short:

A simple Component as the to be used template

@Component({
  selector: 'dt2-simple-block',
  properties: ["idx"],
  template: `<h1>Simple block for  {{ idx }} </h1>`,
  directives: []
})
class dt2SimpleBlock {
  constructor() {
  }
}

Constructor of the Component that holds all Components to be added (my app requires multiple childs to be included:

 constructor(loader: DynamicComponentLoader, elementRef: ElementRef) {

  //iterate
  for (var i = 0; i < toSomething; i++) {
      // build the template
      var blockdirective = 'dt2-simple-block'
      var template = '<' + blockdirective + 
                     ' idx="' + this.userBlocks.userHomePanelBlocks[i] +
                     '"></' + blockdirective + '>';
      console.log(template);   // debugging purpose
      var directives = [dt2SimpleBlock];
        loader.loadNextToLocation(toComponent(template, directives), elementRef);
    }

And the helper function to be put somewhere as util

function toComponent(template, directives = []) {
  @Component({ selector: 'fake-component' })
  @View({ template, directives })
  class FakeComponent { }

  return FakeComponent;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...