【问题标题】:Angular 2: how to use the data passed to component when dynamically created inside component itselfAngular 2:在组件内部动态创建时如何使用传递给组件的数据
【发布时间】:2017-05-24 01:31:01
【问题描述】:

我使用了以下示例Angular 2 Passing data to component when dynamically adding the component,并且由于它,我能够在子组件模板中看到值dataToPass(从父级传递给动态创建的子级),但我无法获得子组件构造函数中的属性,以便对其进行修改。
你知道怎么做吗?

你可以在这里看到我的plunk 和下面的代码:

//our root app component
import {
  NgModule, 
  Input, 
  ComponentRef, 
  Injectable, 
  Component, 
  Injector, 
  ViewContainerRef, 
  ViewChild, ComponentFactoryResolver} from "@angular/core";
import {BrowserModule} from '@angular/platform-browser'
import {Subject} from 'rxjs/Subject';

@Injectable()
export class SharedService {
  showModal:Subject<any> = new Subject();
}

@Component({
  selector: 'comp-comp',
  template: `MyComponent dataToPass: {{dataToPass}}, dataToPass2: {{dataToPass2}}`
})
export class CompComponent {
  dataToPass2;
  constructor() {
      this.dataToPass2 = this.dataToPass+' hello';
  }
}

@Component({
  selector: 'child-component',
  template: `
      <button (click)="showDialog()">show modal from child</button>
  `,
})
export class ChildComponent {
  constructor(private sharedService:SharedService) {}

  showDialog() {
    this.sharedService.showModal.next({'type': CompComponent, 'title': 'titolo2', 'dataToPass': 'dataToPass'});
  }

}

@Component({
  selector: 'modal-comp',
  template: `
  <div class="modal fade" id="theModal" tabindex="-1" role="dialog" aria-labelledby="theModalLabel">
    <div class="modal-dialog largeWidth" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h4 class="modal-title">{{theHeader}}</h4></div>
        <div class="modal-body" #theBody>
      </div>
    <div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal" (close)="close()">Close</button>
  </div></div></div></div>
`
})
export class ModalComponent {
  @ViewChild('theBody', {read: ViewContainerRef}) theBody;

  theHeader: string = '';
  dataToPass: string = '';
  cmpRefBody:ComponentRef<any>;

  constructor(
    sharedService:SharedService, 
    private componentFactoryResolver: ComponentFactoryResolver, 
    injector: Injector) {

    sharedService.showModal.subscribe(data => {
      if(this.cmpRef) {
        this.cmpRef.destroy();
      }
      let factory = this.componentFactoryResolver.resolveComponentFactory(data.type);
      this.cmpRef = this.theBody.createComponent(factory);
      this.cmpRef.instance.dataToPass = data.dataToPass;
      this.dataToPass = data.dataToPass;
      this.theHeader = data.title;
      console.log(data.title);
      console.log(data.dataToPass);
      $('#theModal').modal('show');
    });
  }

  close() {
    if(this.cmpRef) {
      this.cmpRef.destroy();
    }
    this.cmpRef = null;
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello</h2>
      <button (click)="showDialog()">show modal</button>
      <child-component></child-component>
    </div>
  `,
})
export class App {

  constructor(private sharedService:SharedService) {}

  showDialog() {
    this.sharedService.showModal.next({'type': CompComponent, 'title': 'titolo1', 'dataToPass': 'dataToPass'});
  }

}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, ModalComponent, CompComponent, ChildComponent],
  providers: [SharedService],
  entryComponents: [CompComponent],
  bootstrap: [ App, ModalComponent ]
})
export class AppModule{}

【问题讨论】:

    标签: angular data-binding


    【解决方案1】:

    构造函数在你创建组件时执行,这是在你赋值之前。您可以将其设置为能够在传递新值时执行代码:

    export class CompComponent {
      private _dataToPass2;
      get dataToPass2() {
        return this._dataToPass2;
      }
      set dataToPass2(value) {
        this._dataToPass2 = value + 'hello';
      }
    }
    

    【讨论】:

    • 哦,我不知道你可以这样设置。但是,它给了我一个错误: 异常:./CompComponent 类 CompComponent 中的错误 - 内联模板:0:0 原因:超出最大调用堆栈大小 RangeError:CompComponent.get [as dataToPass2] 超出最大调用堆栈大小
    • 对不起,我马虎了。支持字段需要与 getter/setter 不同的名称 - 已修复。
    【解决方案2】:

    感谢 Gunter 的建议,我能够找到解决方案。

    export class CompComponent {
      dataToPass2;
    
      ngAfterContentInit() {
        this.dataToPass2 = this.dataToPass + ' hello';
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 2016-09-26
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 2017-07-07
      相关资源
      最近更新 更多