Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 如何使用模板服务来减少HTML?_Angular_Angular2 Template_Angular2 Directives_Angular Directive - Fatal编程技术网

Angular 如何使用模板服务来减少HTML?

Angular 如何使用模板服务来减少HTML?,angular,angular2-template,angular2-directives,angular-directive,Angular,Angular2 Template,Angular2 Directives,Angular Directive,我有一个包装表单控件的组件。这为每个控件添加了可重用代码,但为了简单起见,假设它只添加了一个标签: 应用程序组件: <app-wrapper labelText="First Name"> <input type="text" > </app-wrapper> <div style="border:thin solid; padding:10px"> <label>{{labelText}}</label>

我有一个包装表单控件的组件。这为每个控件添加了可重用代码,但为了简单起见,假设它只添加了一个标签:

应用程序组件:

<app-wrapper labelText="First Name">
  <input type="text" >
</app-wrapper>
<div style="border:thin solid; padding:10px">
    <label>{{labelText}}</label>
  <ng-content></ng-content>
</div>

export class WrapperComponent {
    @Input() labelText;
}
@Component({
  selector: 'my-app',
  template: `

  <input type="text" wrapper labelText="First Name">
  <input type="text" wrapper labelText="Last Name" >

  <ng-template #tpl>
    <div style="border:thin solid; padding:10px">
        <label>{{labelText}}</label>
      <ng-content></ng-content>
    </div>
  </ng-template>`
})
export class AppComponent {
  @ViewChild('tpl', {read:TemplateRef}) tpl
  constructor(private service: TemplateService) { }

  ngAfterViewInit() {
    this.service.template = this.tpl;
  }
}
不幸的是,我相信这会将标签放在输入标签之后,而不是前面。我怎样才能把它插在前面


另一个问题是:如何访问模板中的#labelText?

我将创建一个具有属性选择器的组件,您可以在包装输入的div上设置该属性选择器。比如:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'div[wrapper]',
  template: `
    <label>{{labelText}}</label>
    <ng-content></ng-content>
  `,
  styles: [`
  :host {
    border:thin solid; 
    padding:10px;
  }
  `]
})
export class WrapperComponent {
  @Input() labelText: string;
}
然后像这样使用它:

<div wrapper [labelText]="'test text'">
    <input type="text">
</div>
<input type="text" *wrapperLabelText="'test';wrapper:wrapperTemplate">
<input type="text" *wrapperLabelText="'test 2';wrapper:wrapperTemplate">

<ng-template #wrapperTemplate let-wrapped="wrapped" let-labelText="labelText">
  <div style="border:thin solid; padding:10px">
    <label>{{labelText}}</label>
    <ng-container *ngTemplateOutlet="wrapped"></ng-container>
  </div>
</ng-template>

{{labelText}}

在我的评论中添加了一个带有结构化指令的示例:我的想法是,如果我使用指令而不是将每个控件包装在组件标记中,HTML将不会那么混乱——但我认为你改变了我的想法。更直接、更灵活。谢谢
import { Directive, Input, ViewContainerRef, TemplateRef, EmbeddedViewRef } from '@angular/core';

@Directive({
  selector: '[wrapperLabelText]',
})
export class WrapperDirective {
  private _labelText: string;
  private embedded: EmbeddedViewRef<any>;

  @Input('wrapperLabelText')
  get labelText() {
    return this._labelText;
  }
  set labelText(value: string) {
    this._labelText = value;
    if (this.embedded) {
      this.embedded.context.labelText = value;
    }
  };

  @Input('wrapperLabelTextWrapper')
  wrapperTemplate: TemplateRef<any>;

  constructor(
    private templateRef: TemplateRef<any>,
    private vc: ViewContainerRef,
  ) {

  }

  async ngAfterViewInit() {
    await new Promise(resolve => setTimeout(resolve));
    const ref = this.vc.createEmbeddedView(this.wrapperTemplate, {
      wrapped: this.templateRef,
      labelText: this.labelText,
    });
  }
}
<input type="text" *wrapperLabelText="'test';wrapper:wrapperTemplate">
<input type="text" *wrapperLabelText="'test 2';wrapper:wrapperTemplate">

<ng-template #wrapperTemplate let-wrapped="wrapped" let-labelText="labelText">
  <div style="border:thin solid; padding:10px">
    <label>{{labelText}}</label>
    <ng-container *ngTemplateOutlet="wrapped"></ng-container>
  </div>
</ng-template>