首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Angular 2中的动态模板URL

Angular 2中的动态模板URL
EN

Stack Overflow用户
提问于 2015-07-29 14:07:40
回答 10查看 67.2K关注 0票数 72

在过去的几天里,我一直在尝试Angular 2,想知道是否有可能为@View装饰器提供一个动态templateUrl

我试着给它传递一个函数,然后返回一个字符串,但是整个函数都变成了一个字符串。

我以前也没有真正使用过Angular 1.x,所以我不知道我是不是用错了方法,但这是可能的吗,或者有没有更好的方法来创建动态视图?

例如,如果用户未登录,我可能希望显示一个表单,但如果用户已登录,则显示一条文本消息。

像这样的东西不起作用:

代码语言:javascript
复制
@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;
  }
}

任何帮助都将不胜感激。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2015-12-03 21:23:43

尽管可能不是最优雅的解决方案,但我使用了DynamicComponentLoader和ElementRef来动态地将模板值分配给组件。事实上,我正在寻找一种可以将多个自定义组件添加到占位符中的解决方案。

我尝试了shmck概述的函数中的服务注入,这不起作用,因为当调用模板函数时,服务还不可用。实际上,this指的是窗口对象。

我使用的解决方案的参考URL可以在以下位置找到:create dynamic anchorName/Components with ComponentResolver and ngFor in Angular2

我也将这种方式引用到Plnkr1Plnkr2

站点Dartdocs提供了关于Angular 2 DynamicComponentLoader类的很好的文档,也适用于TypeScript。

简而言之:

作为要使用的模板的简单组件

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

包含要添加的所有组件的组件的构造函数(我的应用程序需要包含多个childs:

代码语言:javascript
复制
 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);
    }

并将helper函数作为util放在某个位置

代码语言:javascript
复制
function toComponent(template, directives = []) {
  @Component({ selector: 'fake-component' })
  @View({ template, directives })
  class FakeComponent { }

  return FakeComponent;
}
票数 24
EN

Stack Overflow用户

发布于 2016-04-07 13:13:42

我的解决方案是:

Angular 2.0 ViewResolver Class

代码语言:javascript
复制
class myViewResolver extends ViewResolver{
    resolve(component: Type): ViewMetadata {        
        var view =  super.resolve(component);
        // TODO: Write logic here:-)
        view.templateUrl = 'app/app.html';
        return view;
    }
}
bootstrap(App,[
    provide(ViewResolver , {useClass:myViewResolver})
]);
票数 11
EN

Stack Overflow用户

发布于 2016-07-20 21:33:20

不完全符合您的要求,但值得一提的是:

另一个适用于大多数用例的简单解决方案是将逻辑放在模板本身中,如下所示:

代码语言:javascript
复制
@Component({
  selector: 'my-component'
})
@View({
// Note1: Here, I use template instead of templateUrl.
// Note2: I use ES6 string interpolation + require() to embed/load the other templates, but you can do it however you like.
  template: `
    <div [ngSwitch]="loggedIn">
      <template [ngSwitchCase]="true"> ${require('./logged-in.html')} </template>
      <template ngSwitchDefault> ${require('./logged-out.html')} </template>
    </div>`
})
class MyComponent {
  constructor() {
    this.loggedIn = false;
  }
}

这种解决方案的缺点是,您提供的js文件最终包含两个模板,因此这可能是大模板的问题(但实际上只呈现一个模板,并且js大小开销在许多情况下是可以接受的)。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31692416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档