Angular5模板绑定,多次调用回调函数 [英] Angular5 template binding, callback function called more than once

查看:98
本文介绍了Angular5模板绑定,多次调用回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用包含columns definition及其data array的结构化数据来实现网格组件.

I tried to implement a grid component with a structured data containing columns definition and its data array.

每列的定义中都有一个callback函数,用于自定义显示该列的值.

There is a callback function in the definition of each column, to customize displaying the value of that column.

在每个callback的内部,它调用了console.log()来向我显示回调函数将被调用多少次.

Inside of each callback, it called a console.log() to show me how many times the callback function will be called.

我不知道为什么在开始时调用回调函数四次,并在changeSort()事件触发后调用two times!请让我知道.

I don't know why callback function called four times in the beginning, and two times after changeSort() event fired !! Please let me know.

我编写了以下表格组件:

I wrote the following table component:

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

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {

  // @Input() public grid: {
  //   columns: any[],
  //   data: any[]
  // };

  public grid: any;

  constructor() {
    this.grid = {
      columns: [],
      data: [],
    };
  }

  ngOnInit() {
    this.grid = {
      data: [
        {
          desc: 'hello 1',
          header: 'my header 1'
        },
        {
          desc: 'hello 2',
          header: 'my header 2'
        },
        {
          desc: 'hello 3',
          header: 'my header 3'
        }
      ],
      columns: [
        {
          title: 'Description',
          field: 'desc',
          sortable: false,
          callback: (value) => this.myCallback1(value),
        },
        {
          title: 'Header',
          field: 'header',
          sortable: true,
          callback: (value) => this.myCallback2(value),
        },
      ],
    };
  }

  public changeSort(field) {
    console.log(field);
  }

  public myCallback1(value) {
    console.log('myCallback', value);
    return value + ' mc1';
  }

  public myCallback2(value) {
    console.log('myCallback2', value);
    return value + ' mc2';
  }

}

它的模板是这个:

<div class="table-responsive">
  <table class="table table-striped table-sm">
    <thead>
    <tr>
      <th>#</th>
      <th *ngFor="let col of grid.columns">
        <span (click)="changeSort(col)" *ngIf="col.sortable">{{col.title}}</span>
        <span *ngIf="!col.sortable">{{col.title}}</span>
      </th>
    </tr>
    </thead>
    <tbody>
    <tr *ngFor="let row of grid.data; let i = index">
      <td>{{i+1}}</td>
      <td *ngFor="let col of grid.columns">{{col.callback ? col.callback(row[col.field]) : row[col.field]}}</td>
    </tr>
    </tbody>
  </table>
</div>

这是开头的日志错误:

myCallback hello 1
myCallback2 my header 1
myCallback hello 2
myCallback2 my header 2
myCallback hello 3
myCallback2 my header 3
myCallback hello 1
myCallback2 my header 1
myCallback hello 2
myCallback2 my header 2
myCallback hello 3
myCallback2 my header 3
myCallback hello 1
myCallback2 my header 1
myCallback hello 2
myCallback2 my header 2
myCallback hello 3
myCallback2 my header 3
myCallback hello 1
myCallback2 my header 1
myCallback hello 2
myCallback2 my header 2
myCallback hello 3
myCallback2 my header 3

推荐答案

Angular处理模型和dom(组件和模板文件)之间的绑定.为此,应用程序会打勾(更改检测周期)并检查是否有任何值已更改,如果是,则->更新dom.

Angular handles the binding between the model and the dom (component and template file). To do this the application ticks (change detection cycle) and checks for if any values that have changed, and if so -> Update the dom.

问题是当模板文件中有函数时,每个循环角度将调用该函数以检查值"是否已更改.

The problem is when you have functions in your template file, and each cycle angular will call the function to check if the 'value' has changed.

例如,如果我有一个简单的get函数,该函数仅返回一个值,则Angular需要运行它以检查是否确实存在更改.

For example, if I had a simple get function which only returned a value, Angular needs to run it to check that there is actually a change.

{{ myValue() }} // in the template file

myValue() { return 10 } // in the component

在这里有意义的是,角度必须分别调用函数以检查值是否已更改.

Here it makes sense that angular must call the function each to check if the value has changed.

一种解决方案(如果您不希望Angular不断调用您的函数),是实现ChangeDectionStrategy(

A solution (if you don't want Angular to be constantly calling your functions), is to implement a ChangeDectionStrategy (https://angular.io/api/core/ChangeDetectionStrategy). With this, you can tell Angular that you will handle the updates, and when it should run the cycle (for only that component).

为此,您将在组件元数据中添加以下内容:

To do so within the component metadata you will add the following:

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush // the new line
})

然后在构造函数中:

constructor(private changeDetectorRef: ChangeDetectorRef) {}

每当进行更改时,您都可以调用 this.changeDetectorRef.markForCheck(); ,它将手动运行该组件的周期并在需要时更新dom.

Whenever you make a change, you can then call this.changeDetectorRef.markForCheck(); which will manually run the cycle for this component and update the dom when needed.

我真的建议您多读一读,因为这个话题太广泛了,无法在这篇文章中描述

I really suggest reading into this more as the topic is too broad to describe in this one post

这篇关于Angular5模板绑定,多次调用回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆