【问题标题】:How can i watch value change in angular 4?我如何观察角度 4 的值变化?
【发布时间】:2019-04-15 21:14:24
【问题描述】:

我已经为我的组件 [grid] 创建了自定义管道。在管道声明中,我可以获取我的组件实例,但同时我想获取我的数据源值是否在管道声明中发生变化。有可能得到吗?

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { GridAllModule } from '@syncfusion/ej2-angular-grids';
import { NumericTextBoxAllModule } from '@syncfusion/ej2-angular-inputs';
import { ToolbarModule } from '@syncfusion/ej2-angular-navigations';

import { AppComponent, DefaultPipe, DefaultPipe1 } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
    DefaultPipe,
    DefaultPipe1
  ],
  imports: [
    BrowserModule, GridAllModule, ToolbarModule, NumericTextBoxAllModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

platformBrowserDynamic().bootstrapModule(AppModule);

app.component.ts

   
import {
  NgModule, Component, Pipe, PipeTransform, OnInit, Input, IterableDiffers, DoCheck,
  ViewChild, ChangeDetectorRef, SimpleChanges, WrappedValue, SimpleChange, OnChanges
} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { orderDetails } from './data';
import { orderDetails1 } from './datas';
import { GridComponent } from '@syncfusion/ej2-angular-grids';

// import { SidebarService } from './service';


@Pipe({ name: 'defaultImage' })
export class DefaultPipe implements PipeTransform {
  transform(value: string, fallback: string, ): string {
    let image = '';
    if (value) {
      image = value;
    } else {
      image = fallback;
    }
    return image;
  }
}

@Pipe({
  name: 'defaultImage1',
  pure: false
})
export class DefaultPipe1 implements PipeTransform {

  constructor(private _ref: ChangeDetectorRef) { }

  transform(value: string, fallback: string, ): string {
     // let Data1 = '';
// if (value.length !== 0) {
//   Data1 = value;
// } else {
//   Data1 = fallback;
// }
// return Data1;
  }
}

@Component({
  selector: 'app-my',
  template: `
  <img [src]="imageUrl | defaultImage:'http://s3.amazonaws.com/uifaces/faces/twitter/sillyleo/128.jpg':true"/>

  <div class="control-section">
    <ejs-grid #gridref id='check' [dataSource]='data | defaultImage1:gridref' height='350'>
    <e-columns>
    <e-column field='OrderID' headerText='Order ID' textAlign='Right' width=90></e-column>
    <e-column field='CustomerID' headerText='Customer ID' width=120></e-column>
    <e-column field='Freight' headerText='Freight' textAlign='Right' format='C2' width=90></e-column>
    <e-column field='OrderDate' headerText='Order Date' textAlign='Right' format='yMd' width=120></e-column>
</e-columns>
    </ejs-grid>
</div>
 `
})
export class AppComponent implements OnInit, DoCheck {
  imageUrl: String = '';

  public data: Object[] = [];


  @ViewChild('gridref')
  public refGrid: GridComponent;



  ngOnInit(): void {
    this.data = orderDetails;

  }

 
}

在这里,我已经初始化了我的管道,如下所示:

&lt;ejs-grid #gridref id='check' [dataSource]='data | defaultImage1:gridref' height='350'&gt;

我试过这样 [http://blog.bogdancarpean.com/how-to-watch-for-changes-an-arrayobject-on-angular-2/] 但我无法达到我的要求

  @Input() data: Object[] = [];

  differ: any;
  constructor(differs: IterableDiffers) {
    this.differ = differs.find([]).create(null);
  }
  ngDoCheck() {
    const change = this.differ.diff(this.data);
    console.log(change);
  }

在这种情况下,我怎样才能达到我的要求。请提供任何想法。

【问题讨论】:

  • 虽然您提供了当前实现的代码,但您对问题的陈述并不清楚。请明确说明您想要达到的目标,以便我们为您提供帮助。
  • @NabilShahid,感谢您的回复。我想在数据源值更改时检测管道声明中的更改
  • 管道动态工作,即如果数据源发生变化,管道将应用于数据源的新值。您想对管道中的数据源更改执行其他操作吗?
  • @NabilShahid,我想在管道内使用更改后的数据源值。
  • 我想我有这个问题。请看我的回答。

标签: angular typescript observable angular2-custom-pipes


【解决方案1】:

有两种类型的管道。纯与不纯。在纯管道的情况下,仅当 angular 检测到传递给管道的值或参数发生变化时,才会调用管道的转换函数。在不纯管道中,无论管道的值或参数是否发生变化,都会在每个变化检测循环中调用它。 由于您的管道是纯的,因此转换函数没有调用,因为datasource 是一个对象数组,所以角度没有检测到它的值被修改,因为值即data 是一个数组,而不是原始类型,即(字符串,布尔值, int 等)您可以通过三种方式解决此问题:

1.在您的逻辑更改data之后执行以下代码行,这将为data分配一个新对象,这将调用管道,即管道的trasnform函数将执行,您将获得数据源的新价值:

var tempVar= this.data; 
this.data= []; 
Object.assign(this.testVal, tempVar);

只要更新this.data 即只需运行以上三行即可

2.将您的管道改为不纯的。然而,这将是低效的,因为每次角度运行更改检测时都会调用转换,从而使您的应用程序变慢。 您可以这样做,即在 @Pipe 装饰器中将纯标志设置为 false:

@Pipe({
  name: 'defaultImage',
  pure: false
})
  1. 为管道使用临时原始类型参数,并根据data 的变化更新其值,这将导致管道的转换函数使用新数据源执行,例如在您的 html 中:

将其添加到变换函数中,即:

transform(value: string, fallback: string, tempParam)

并在您的逻辑中更改 data 时更改其值。

【讨论】:

  • 在第三个答案中,我想知道如何在 tempParam 中获取我的数据源值,以及如何在数据源值发生变化时更新
  • 在第3个答案中,tempParam仅用于调用管道的transform函数。关于数据源,它已经被传递到您的管道。它将位于transform 函数的value 变量中。有关如何在管道中传递参数的更多信息,请参阅此处接受的答案:stackoverflow.com/questions/36816788/…
  • 尝试在转换函数中在image = value;这一行之后添加console.log值,它将是数据源,即this.data。如果您仍然无法实现您正在寻找的东西,请生成您当前实现的堆栈闪电战,我会尝试实现您在其中寻找的东西。
  • 再次感谢您。我的要求是在管道 decalration [DefaultPipe1] 中,我使用了我的数据源。我需要的是,如果该数据源值发生更改,那么我必须将该更改后的值存储在管道声明内的一个变量中。
  • 嗨。为了将值存储在管道中,您需要使该管道不纯,否则一旦管道的转换函数返回,保存在该管道中的任何变量都将被销毁。但是,如果您使管道不纯,则可以存储该值,但正如我在答案中提到的那样效率低下。我建议您创建另一个类而不是管道来执行此类操作并存储值而不是管道。
猜你喜欢
  • 1970-01-01
  • 2018-03-01
  • 2018-09-24
  • 1970-01-01
  • 1970-01-01
  • 2014-10-21
  • 2022-12-15
  • 2021-01-31
相关资源
最近更新 更多