简体   繁体   中英

Angular2 parse directive template ng-container

I am new to angular2 and tried with dynamic form and its field generation by referring this URL . And i got the form as expected.

Since the dynamic form component render the field one by one using ng-container as shown below by loop it

<ng-container
        *ngFor="let field of config;"
        dynamicField
        [config]="field"
        [group]="form">
      </ng-container>

I am using the form template as shown below

<dynamic-form
        [config]="config"
        #form="dynamicForm"
        (submit)="submit($event)">
      </dynamic-form>

I want to render the template inside dynamic-form as two column not one by one.Basically i want to define the html field position placing inside dynamic-form directive. For example

<dynamic-form
    [config]="config"
    #form="dynamicForm"
    (submit)="submit($event)">
    <div class="clearfix">
            <div class="col-md-6 col-sm-6" id="FIRST_NAME"></div>
            <div class="col-md-6 col-sm-6" id="LAST_NAME"></div>
        </div>
  </dynamic-form>

How <ng-container> could help to replace the respective field which we given in our directive template. Or Suggest best way to render html in defined position dynamically using dynamic-form component.

Expected output, 在此输入图像描述

Please advise

You can create directive that will keep reference to ViewContainerRef . This way it will be possible to place the field wherever you want.

So let's try to describe how we can do that.

First, create directive like:

dynamic-form-field-place.directive.ts

@Directive({
  selector: '[dynamic-form-placeId]'
})
export class DynamicFormFieldPlaceDirective {
  @Input('dynamic-form-placeId') placeId: string;

  constructor(public vcRef: ViewContainerRef) {}
}

The directive just takes dynamic-form-placeId @Input and we also inject ViewContainer to get hold reference to it. As you will see later it will be used in DynamicFieldDirective provided by Todd Motto.

After that we mark places for our dynamic fields

<dynamic-form
    [config]="config"
    #form="dynamicForm"
    (submit)="submit($event)">
  <div class="row">
    <div class="col-md-6 col-sm-6">
      <ng-container dynamic-form-placeId="FirstName"></ng-container>
    </div>
    <div class="col-md-6 col-sm-6">
      <ng-container dynamic-form-placeId="LastName"></ng-container>
    </div>
  </div>
  <div class="row">
    <div class="col-md-6 col-sm-6">
      <ng-container dynamic-form-placeId="Gender"></ng-container>
    </div>
    <div class="col-md-6 col-sm-6">
      <ng-container dynamic-form-placeId="Food"></ng-container>
    </div>
  </div>
</dynamic-form>

then modify

dynamic-form.component.html

<form
    class="dynamic-form"
    [formGroup]="form"
    (submit)="handleSubmit($event)">
  <ng-content></ng-content> // we transclude markup
  <ng-container
        *ngFor="let field of config;"
        dynamicField
        [container]="containers[field.name]" // and pass viewContainerRef
        [config]="field"
        [group]="form">
  </ng-container>
</form>

dynamic-form.component.ts

@ContentChildren(DynamicFormFieldPlaceDirective) places: 
                           QueryList<DynamicFormFieldPlaceDirective>;

containers = {};

ngAfterContentInit() {
  this.places.forEach(x => this.containers[x.placeId] = x.vcRef);
}

And finally let's modify DynamicFieldDirective

dynamic-field.directive.ts

@Input() container: ViewContainerRef;

ngOnInit() {
  ...
  const container = this.container || this.vcRef;
  ...
}

In the preceding code i use ViewContainerRef that was provided by us earlier.

If you want to look at completed code just open

Plunker Example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM