Angular: 使用变量更改组件模板

Angular: Change component template using variables

我的问题是:当父控制器中的变量值发生变化时,是否可以更改组件模板? 这里有两种我尝试遵循的方法:

var topBarTemplateWithButton = [
'<section id="filters">',
'<div class="pull-left">',
'<h1>{{$ctrl.step}}</h1>',
'<div class="pull-left pageActionContainer">',
'<ng-transclude></ng-transclude>',
'</div>',
'</div>',
'</section>'].join(' ')

var topBarTemplateWithoutButton = [
    '<section id="filters">',
    '<div class="pull-left">',
    '<h1>{{$ctrl.step}}</h1>',
    '</div>',
    '</section>'].join(' ')

myApp.component('topBar', {
    bindings: {
        step: '<'
    },
    template: this.templateToUse,
    transclude: true,
    controller: function() {
        var me = this;

        me.$onInit = function() {
            this.templateToUse = topBarTemplateWithButton;
        }

        me.$onChanges = function(changes) {
            if(changes.step.currentValue != "Projects") {
                this.templateToUse = this.topBarTemplateWithoutButton;
            }else {

                this.templateToUse = topBarTemplateWithButton;

            }
        }
    }
});

var topBarTemplateWithButton = [
    '<section id="filters">',
    '<div class="pull-left">',
    '<h1>{{$ctrl.step}}</h1>',
    '<div class="pull-left pageActionContainer">',
    '<ng-transclude></ng-transclude>',
    '</div>',
    '</div>',
    '</section>'].join(' ')

var topBarTemplateWithoutButton = [
    '<section id="filters">',
    '<div class="pull-left">',
    '<h1>{{$ctrl.step}}</h1>',
    '</div>',
    '</section>'].join(' ')

myApp.component('topBar', {
    bindings: {
        step: '<'
    },
    template: '<div ng-include="$ctrl.templateToUse"/>,
    transclude: true,
    controller: function() {
        var me = this;

        me.$onInit = function() {
            this.templateToUse = topBarTemplateWithButton;
        }

        me.$onChanges = function(changes) {
            if(changes.step.currentValue != "Projects") {;
                this.templateToUse = this.topBarTemplateWithoutButton;
            }else {
                this.templateToUse = topBarTemplateWithButton;
            }
        }
    }
});

这两个例子都不行。那么是不是可以在step的值改变的时候改变这个组件的模板呢?感谢您的帮助。

Template字段可以是一个returns模板的函数,它以attrs作为可注入的。这是一个可能会完成您正在寻找的示例。

template: function(attrs) {
    "ngInject";
    // check for custom attribute and return different template if it's there
},

但是重要的一点是,此时这些是 未编译 属性,因为模板尚未编译。实际上,在确定模板之前,它不能被编译。所以你检查的它们的属性只能是字符串文字..

我认为为一个组件使用两个不同的模板不是最佳做法。主要规则是在一个视图中使用一个控制器。因此,从这个角度来看,实现此行为的更好方法是在组件模板内使用 ng-switchng-if,甚至制作两个不同的 dumb 组件 - topBarWithButtontopBarWithoutButton.在这两种情况下,您都通过绑定与组件进行交互。我认为使用 attrs 而不是 bindings 有点老套。组件不是指令,因此在构建基于组件的应用程序时,您必须从组件的角度考虑。我认为您不应该使用 attrs 的原因有很多:

  1. 编译后无法更改模板。
  2. 您不能更改组件的状态。
  3. 您在 html 模板中保持状态。
  4. 测试这种方法并不容易。