ngModel无法在动态组件中工作。 Angular 2

时间:2017-03-07 15:39:35

标签: angular dynamic ionic2 components

我得到了通过动态创建组件的服务。在模板中我使用ngModel指令。但我得到了一个错误:

Uncaught (in promise): Error: Template parse errors: Can't bind to 'ngModel' since it isn't a known property of 'input'.

这是一段代码。

我创建动态组件的组件:



import {
  Component, Input, ElementRef, ViewChildren, ViewContainerRef,
  QueryList, ComponentFactoryResolver, ComponentRef, ComponentFactory, OnDestroy
} from '@angular/core';
import { AbstractBlock } from "../../abstractblock";
import { HttpRequestService } from "../../../services/httprequestservice";
import { ToastController, Events, NavController, NavParams } from "ionic-angular";
import { AuthService } from "../../../services/authservice";
import { CartService } from "../../../services/cartservice";
import { ConfigService } from "../../../services/configservice";
import { CheckoutService } from "../../../services/checkoutservice";
import { HelperTools } from "../../../services/helpertools";
import { Delivery } from "../../../models/checkout/delivery";
import { CheckoutWarehousePage } from "../warehousepage";
import { CheckoutConfirmPage } from "../confirmpage";
import { APP_CONFIG } from "../../../app/app.config";
import { Http } from "@angular/http";
import { CheckoutDeliveryAdditionalHTML} from "../deliveryadditionalhtml";
import { DynamicDeliveryAdditionalHTML, DeliveryDynamicData } from "../../../services/dynamicdeliveryadditionalhtml";


@Component({
  selector: 'checkout-blocks-deliverypayment',
  templateUrl: "
  <ion-list *ngIf="delivery_list.length">
      <ion-item [ngClass]="{'checked': (delivery.checked)}" *ngFor="let delivery of delivery_list" (click)="onDeliveryChange(delivery)" text-wrap>
        <h2>{{delivery.title}}</h2>
        <div #additionalHTML id="deliveryAdditionalHTML{{delivery.id}}" class="additionalInfo">

        </div>
      </ion-item>
  </ion-list>
  "
})

export class CheckoutBlocksDeliveryPayment extends AbstractBlock implements OnDestroy{

  delivery_list     = [];
  current_delivery: Delivery;
  shop_config; 
  childComponent: ComponentRef<any>;

  @ViewChildren("additionalHTML", {read: ViewContainerRef}) additionalHTML: QueryList<ViewContainerRef>;

  constructor(
              public http: Http,
              public httpRequestService: HttpRequestService,
              public toastCtrl: ToastController,
              public authService: AuthService,
              public _elementRef : ElementRef,
              public typeBuilder : DynamicDeliveryAdditionalHTML,
              public cartService: CartService,
              public configService: ConfigService,
              public checkoutService: CheckoutService,
              public navCtrl: NavController,
              public navParams: NavParams,
              public componentFactoryResolver: ComponentFactoryResolver,
              public events: Events)
  {
    super(toastCtrl, _elementRef);
    let delivery_info = navParams.get('delivery');
    if (delivery_info && delivery_info['list']){ 
      this.delivery_list  = HelperTools.getList(delivery_info['list'], Delivery);
    }
    this.shop_config = this.configService.configs['shop'];
  }


  ngOnInit():void {}


  /**
  * Adding new component in current
  */
  private fillAdditionalDeliveryHtml()
  {
    if (this.childComponent){
      this.childComponent.instance.destroy();
    }
    if (this.current_delivery.isHaveAdditionalHtml()){

      this.additionalHTML.forEach((el: ViewContainerRef) => {
      
        if (el.element.nativeElement.getAttribute('id') == ("deliveryAdditionalHTML" + this.current_delivery.id)){
          this.typeBuilder
            .createComponentFactory('<input type="hidden" [(ngModel)]="current_delivery.info" [value]="'myValue'"/>')
            .then((factory: ComponentFactory<DeliveryDynamicData>) =>
            {
              this.childComponent = el.createComponent(factory);
              this.childComponent.instance.delivery_list     = this.delivery_list;
              this.childComponent.instance.current_delivery  = this.current_delivery;
              this.childComponent.instance.shop_config       = this.shop_config;
            });
        }
      });
    }

  }

  /**
  * On change delivery
  */
  onDeliveryChange(delivery: Delivery)
  {
    this.delivery_list.forEach((del: Delivery) => {
      del.checked = false;
    });
    delivery.checked = true;
    this.current_delivery = delivery;
    this.fillAdditionalDeliveryHtml();
  }



  public ngOnDestroy(){
    if (this.childComponent){ 
      this.childComponent.instance.destroy();
    }
  }
}
&#13;
&#13;
&#13;

我动态创建组件的服务:

&#13;
&#13;
import { Component, Injectable } from '@angular/core';
import { JitCompiler } from "@angular/compiler";
import { DynamicModule } from './dynamic.module';
import { DynamicTypeBuilder } from "./dynamictypebuilder";
import { Delivery } from "../models/checkout/delivery";


export interface DeliveryDynamicData {
  delivery_list: any; 
  current_delivery: any; 
  shop_config; 
}

@Injectable()

export class DynamicDeliveryAdditionalHTML extends DynamicTypeBuilder{

  constructor(
    protected compiler: JitCompiler
  ) {
    super(compiler);
  }


  public createNewComponent (tmpl: string) {
    @Component({
      selector: 'delivery-additional-html',
      template: tmpl
    })
    class CustomDeliveryAdditionalHTML implements DeliveryDynamicData {
      delivery_list     = [];
      current_delivery: Delivery;
      shop_config; 
      entity: any;
    }
    return CustomDeliveryAdditionalHTML;
  }
}
&#13;
&#13;
&#13;

服务的父母:

&#13;
&#13;
import { Component, ComponentFactory, NgModule, Input, Injectable } from '@angular/core';
import { JitCompiler } from "@angular/compiler";
import { DynamicModule } from './dynamic.module';
import {FormsModule} from "@angular/forms";
import _ from "lodash";



export interface IHaveDynamicData {
  entity: any;
}

@Injectable()

export class DynamicTypeBuilder {


  constructor(protected compiler: JitCompiler) {

  }

  private _cacheOfFactories: {[templateKey: string]: ComponentFactory<any>} = {};


  public createComponentFactory(template: string): Promise<ComponentFactory<any>> {

    let factory = this._cacheOfFactories[template];

    if (factory) {
      console.log("Module and Type are returned from cache");

      return new Promise((resolve) => {
        resolve(factory);
      });
    }

    let type   = this.createNewComponent(template);
    let module = this.createComponentModule(type);

    return new Promise((resolve) => {
      this.compiler
        .compileModuleAndAllComponentsAsync(module)
        .then((moduleWithFactories) =>
        {
          factory = _.find(moduleWithFactories.componentFactories, { componentType: type });
          this._cacheOfFactories[template] = factory;
          resolve(factory);
        });
    });
  }


  public createNewComponent (tmpl: string) {
    @Component({
      selector:'dynamic-component',
      template:tmpl
    })
    class CustomDynamicComponent  implements IHaveDynamicData {
      @Input() public entity: any;
    }
    return CustomDynamicComponent;
  }


  public createComponentModule (componentType: any) {
    @NgModule({
      imports: [
        FormsModule
      ],
      declarations: [
        componentType
      ],
    })
    class RuntimeComponentModule {}

    return RuntimeComponentModule;
  }
}
&#13;
&#13;
&#13;

为什么我收到错误?

SOLUTION:

代码工作正常。问题出在Google Chrome缓存中。

0 个答案:

没有答案