【问题标题】:How to trigger a change in value with ngOnchanges?如何使用 ngOnchanges 触发值的变化?
【发布时间】:2020-11-21 07:56:58
【问题描述】:

我有一个父组件和一个可重用的子组件。我想在不使用任何提交按钮的情况下触发子组件中的值并在父组件中的输入更改时显示结果。每当输入值发生任何变化时,我都想调用带有更新值的子组件或可重用组件的 mySubmit() 函数,因为它负责渲染图形。

在父组件(app.component.ts)中:-

*export class AppComponent implements OnInit  {

  title = 'stl-app';
  filename:string=""abc;
  colorname:string ='red';
  perspective:string='35';

  @ViewChild(reusableAppComponent) child:reusableAppComponent;

  constructor(){}

  ngOnInit():void{

  }

  ngOnChanges(changes:SimpleChanges){
        this.child.mySubmit();
  }

 ngAfterViewInit(){
    this.child.mySubmit();
  }

   changedcolor(ev :Event){

    let c=(<HTMLSelectElement>ev.target).value;
    console.log("Hello" + c);
    this.colorname=c;
    this.child.mySubmit();

  } 
}*

在父component.html文件(appcomponent.html)中:-

*

<div>
<reusable-app [filename]= "filename" [colorname] = "colorname" [perspective]= "perspective"></reusable-app>
</div>
<div class="stl" style="position:absolute; right:500px;">
<mat-form-field style="width:600px">
  <mat-label>Name of the file</mat-label>
  <mat-hint> File path of only stl file</mat-hint>
  <input  matInput [(ngModel)]="filename"  name="filename"  required>
  </mat-form-field>
<br><br>
  <mat-form-field>
    <mat-label>Camera Perspective</mat-label>
    <mat-hint> values in Integer</mat-hint>
    <input  matInput [(ngModel)]="perspective"  name="perspective"  required> 
    </mat-form-field>
    <br><br>
    <mat-form-field>
      <mat-label>Select a Color</mat-label>
      <mat-select (change) ="changedcolor($event) [(ngModel)]="colorname" name="colorname" required>
        <mat-option>None</mat-option>
        <mat-option value="red">red</mat-option>
        <mat-option value="blue">blue</mat-option>
        <mat-option value="orange">orange</mat-option>
        </mat-select>
    </mat-form-field>
  </div>

在子component.ts(Reusableappcomponent.ts)中:-

*export class ReusableAppComponent implements OnInit {
  
@Input()
filename:string;
@Input()
colorname:any;
@Input()
perspective:number;

private scene: Scene;
private camera: PerspectiveCamera;
private renderer: WebGLRenderer;
@ViewChild("myCanvas") myCanvas:any;

  constructor(private service:ImlStlAppService,private render:Renderer2,private http: HttpClient,private sanitizer: DomSanitizer) {
   }

  ngOnInit(): void {
     //add listener for the resize of the window - will resize the renderer to fit the window
     let global = this.render.listen('window', 'resize', (evt) => {
      this.onWindowResize();
    })
  }
  mySubmit(){

//Render using the input parameters

}

}*

在子component.html(ReusableComponent.html)中:

*<div style="text-align:center">
<canvas #myCanvas id="myCanvas">
</canvas>
</div>*

我很困惑为什么当我更改输入中的值时渲染没有改变。

【问题讨论】:

  • 您没有实现 OnChangesngOnChanges 仅在 @Input 变量发生更改时触发。但是你的父组件中没有@Input 变量
  • 那我现在应该怎么处理呢?没有ngOnchanges有什么办法吗?
  • 我同意@SivakumarTadisetti,您可以在父母的模板中使用(ngModelChange) 来调用this.child.submit 而不是ngOnChanges
  • @StPaulis - 当我这样做时 (ngModelChange)="this.child.mySubmit()" ,变化正在发生,但它不是同时变化。当进行 2 次更改时,第一个更改更改正在反映。为什么会这样?我做错什么了吗?
  • 小心,顺序很重要,如果你把 ngModel 放在 ngModelChange 上面,它会先调用,否则相反。

标签: javascript angular ngonchanges


【解决方案1】:

您正在寻找的是父组件和子组件之间的反应式通信。有多种方法可以做到这一点。不相关组件之间的常用方法是使用单例服务。

但是由于您已经与组件建立了兄弟关系,您可以将 @Input 装饰器附加到 setter 而不是成员变量。这会在父组件中相应变量发生更改时触发 setter。

试试下面的

父控制器

export class AppComponent implements OnInit {
  title = 'stl-app';
  filename: string = ""
  abc;
  colorname: string = 'red';
  perspective: string = '35';

  constructor() { }

  ngOnInit(): void { }

  changedcolor(ev: Event) {
    let c = ( < HTMLSelectElement > ev.target).value;
    console.log("Hello" + c);
    this.colorname = c;
    this.child.mySubmit();
  }
}

儿童控制器

export class ReusableAppComponent implements OnInit {
  _filename: string;
  @Input() colorname: any;
  @Input() perspective: number;

  @Input() 
  public set filename(name: string) {
    this._filename = name;
    this.mySubmit();           // <-- trigger the call here
  }

  private scene: Scene;
  private camera: PerspectiveCamera;
  private renderer: WebGLRenderer;
  @ViewChild("myCanvas") myCanvas: any;

  constructor(private service: ImlStlAppService, private render: Renderer2, private http: HttpClient, private sanitizer: DomSanitizer) {}

  ngOnInit(): void {
    //add listener for the resize of the window - will resize the renderer to fit the window
    let global = this.render.listen('window', 'resize', (evt) => {
      this.onWindowResize();
    })
  }

  mySubmit() {
    //Render using the input parameters
  }
}

我只将filename 输入设置为setter,因为这似乎是您感兴趣的内容。但是,如果您希望在任何输入变量发生更改时触发mySubmit(),您可以使每一个他们是二传手。

【讨论】:

    【解决方案2】:

    你可以 ngOnChanges(changes:SimpleChanges){ this.mySubmit(); } 在子组件中。 记得写 ReusableAppComponent 实现 OnChanges

    【讨论】:

      猜你喜欢
      • 2018-06-21
      • 2017-07-02
      • 2019-01-30
      • 2011-09-05
      • 2019-04-21
      • 1970-01-01
      • 2017-09-18
      • 2019-11-15
      • 2018-01-20
      相关资源
      最近更新 更多