【问题标题】:One Component Multiple Templates based on Condition基于条件的一个组件多个模板
【发布时间】:2016-10-04 17:18:20
【问题描述】:

所以这就是交易。我有一个写得很好并且在很多地方都使用的组件。现在我需要使用相同的组件,但希望根据条件呈现不同的模板。

我尝试了很多。

1) 尝试使用多个组件装饰器 - 不走运

2) 尝试了多层次的抽象,我最终创建了更多的组件 - 坏主意

3) 可以从字面上复制整个组件,只需更改选择器和模板 - 坏主意

4) 目前我正在尝试这个:

<div *ngIf="!isWizard">
    <ul class="nav" role="tablist">
        <ng-content select="tab-link"></ng-content>
    </ul>
    <ng-content select="tab-content"></ng-content>
</div>


<div *ngIf="isWizard">
    <nav class="nav-panel sidenav">
        <ng-content select=".wizard-title"></ng-content>
            <ul class="nav" role="tablist">
                <ng-content select="tab-link"></ng-content>
            </ul>

    </nav>

    <main class="settings-panel content-area">
        <ng-content select="tab-content"></ng-content>
    </main>

</div>

我将 isWizard 属性设置为真/假。 现在的问题是,ng-content 只运行一次。所以当 isWizard 为真时,即使显示了 div 块,ng-content 也不会运行(因为它在上面的块中运行)。

5) 我也尝试了 ngSwitch 而不是使用 ngIf - 没用

我现在很绝望。请帮忙:)

【问题讨论】:

  • 您使用的是什么 Angular2 版本。据我记得这是最近修复的一个问题。不确定此修复程序是否已包含在 RC.1 中
  • @GünterZöchbauer 我正在使用 2.0.0-rc.1,但不起作用。
  • 建议下次更新后再试。上一次更新是很久以前的事了,那个修复不是很久以前,不记得确切但我很确定它解决了这个问题。
  • @GünterZöchbauer 我找不到确切的链接,但我在某个地方发现 ng-content 应该只运行一次,这就是它的开发方式。所以这就是我依赖 ngIf 和 ngSwitch 的原因(所以 ngContent 运行一次),但即使这些也不起作用。
  • 计划对此要求提供更好的支持,看起来 Material 组件也需要它。

标签: angular angular2-template angular2-directives


【解决方案1】:

或许,我们可以试试这里的解决方案,angular 2 include html templates

我对这个解决方案非常满意,因为我遇到了同样的情况,比如根据某些值切换模板,最终不会用大量的行弄乱代码。

我只是稍微描述一下我的项目结构,以便澄清,

Component Structure
====================
Comp A
 -> Comp a1
 -> Comp a2 
 -> Comp a3 
 -> Comp a-consolidated*(declaring all needed component's selectors) 
Comp B 
Comp C 
Comp D 

这适用于我的问题,我推荐这个:)

【讨论】:

    【解决方案2】:

    在上述最新版本中,可以使用*ngIf="somevar" 完成,而您可以使用@input 传递“somevar”值。

    例子:

    import { Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
    import {SearchPipe} from './../filters/search.pipe';
    
    @Component({
      selector: 'itra-filter',
      templateUrl: 'filter.component.html',
      styleUrls: ['filter.component.scss'],
      inputs:['IsCheckboxEnabled','IsRadioboxEnabled'],
      outputs: ['itemClicked']
    })
    export class ItraFilterComponent {
    	// Default Value
    	public IsCheckboxEnabled:boolean = false;
    	public IsRadioboxEnabled:boolean = false;
    
    	constructor() {		
    	}
    
    	ngOnInit() {
    		
    	}
    }
    <span class="checkbox-control" *ngIf="IsCheckboxEnabled">
            <i class="icon icon_Check-box_filled"   *ngIf="y.checked"></i>
    				<i class="icon icon_Check-box" *ngIf="!y.checked">        </i>
    </span>
          
    <span class="radiobox-control" *ngIf="IsRadioboxEnabled">
    				<i class="icon icon_Radio-button-filled" *ngIf="y.checked"></i>
    				<i class="icon icon_Radio-button" *ngIf="!y.checked"></i>
    </span>

    【讨论】:

      【解决方案3】:

      据我所知,使用ng-content 无法做到这一点,但您可以使用templates(或Angular 4+ 中的ng-templates)来实现。因此,不要将内容直接传递给您的组件,只需将其包装在 &lt;template&gt; 中即可:

      <my-component [isWizard]="true">
          <template>Hello World!</template>
      </my-component>
      

      然后您需要使用@ContentChild(TemplateRef) 将模板注入到您的组件中,并根据需要多次渲染。

      @Component({
        selector: "my-component",
        template: `
          <div *ngIf="!isWizard">
            first: <template [ngTemplateRenderer]="template"></template>
          </div>
          <div *ngIf="isWizard">
            second: <template [ngTemplateRenderer]="template"></template>
          </div>`
      })
      export class MyComponent {
      
        @ContentChild(TemplateRef)
        private template: TemplateRef<any>;
      
        @Input("isWizard")
        private isWizard: boolean;
      }
      

      还有最后一件事,我们的组件使用ngTemplateRenderer,这是一个简单的实用指令,用于呈现通过引用传递的模板。这是该指令的代码:

      @Directive({ selector: '[ngTemplateRenderer]'})
      export class TemplateRenderer implements OnInit, OnDestroy {
      
          @Input("ngTemplateRenderer")
          private template: TemplateRef<any>;
      
          private view: EmbeddedViewRef<any>;
      
          constructor(private container: ViewContainerRef) {}
      
          ngOnInit(): void {
            this.view = this.container.createEmbeddedView(this.template);
          }
      
          ngOnDestroy(): void {
            this.view.destroy(); 
          }
      }
      

      【讨论】:

      • 可以加plnkr或者jsBin的例子吗?
      • 如果我们有多个模板怎么办 而在my-component我们要有条件地显示任何模板。模板电子邮件或姓名。
      猜你喜欢
      • 1970-01-01
      • 2017-09-13
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      • 2011-04-24
      • 1970-01-01
      • 2014-09-27
      相关资源
      最近更新 更多