收到数据后Angular2应用Pipe [英] Angular2 applying Pipe after data is received

查看:90
本文介绍了收到数据后Angular2应用Pipe的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Object,用于管理从后端接收的数据. 它以所有字段都以display: false开头,如果我从服务器收到该特定字段,则最终将其更改为true.

I have an Object that is used to manage the data received from the back end. It is initiated with all the fields as display: false, and if I receive that specific field from the server, I will eventually change it to true.

filterGroups(初始):

export let filterGroups: any = {
    genericFilters: {
        iboId: {
            'display': false,
            'template': ''
        },
        iboCode: {
            'display': false,
            'template': 'text/iboCode'
        },
        iboName: {
            'display': false,
            'template': 'text_input_iboName'
        },
        iboSurname: {
            'display': false,
            'template': 'text_input_iboSurname'
        },
        iboRank: {
            'display': false,
            'template': 'select/multi_iboRank',
        },
        iboEmail: {
            'display': false,
            'template': 'text_input_iboEmail'
        },
        iboNewsletter: {
            'display': false,
            'template': 'select/simple_iboNewsletter',
        },
    },
    orderFilters: {
        iboTotalOrders: {
            'display': false,
            'template': 'compound/iboTotalOrders',
        }
    },
    peFilters: {
        iboTotalPE: {
            'display': false,
            'template': 'checkbox/iboTotalPE',
        }
    },
};

在我的模板中,我希望具有与过滤器组一样多的div.在这种情况下,我们有3个过滤器组:genericFiltersorderFilterspeFilters.

In my template, I want to have as many div as filter groups. In this case we have 3 filter groups: genericFilters, orderFilters and peFilters.

当我从服务器(在我的constructor中调用该数据)接收到数据后,将立即修改此Object.

This Object will be modified as soon as I receive data from the server (which I call in my constructor).

因此,我从异步呼叫接收到数据后,我的filterGroups会看起来像这样.

And so, my filterGroups will look like this after I have received the data from my async call.

filterGroups(异步调用后):

export let filterGroups: any = {
    genericFilters: {
        iboId: {
            'display': true,
            'template': ''
        },
        iboCode: {
            'display': true,
            'template': 'text/iboCode'
        },
        iboName: {
            'display': true,
            'template': 'text_input_iboName'
        },
        iboSurname: {
            'display': true,
            'template': 'text_input_iboSurname'
        },
        iboRank: {
            'display': false,
            'template': 'select/multi_iboRank',
        },
        iboEmail: {
            'display': true,
            'template': 'text_input_iboEmail'
        },
        iboNewsletter: {
            'display': false,
            'template': 'select/simple_iboNewsletter',
        },
    },
    orderFilters: {
        iboTotalOrders: {
            'display': true,
            'template': 'compound/iboTotalOrders',
        }
    },
    peFilters: {
        iboTotalPE: {
            'display': false,
            'template': 'checkbox/iboTotalPE',
        }
    },
};

现在,在我的模板中,我有这个:

Now, in my template I have this:

模板(HTML):

<div *ngFor="let group of filterGroups | keysCheckDisplay">
    <div>
        <h4>{{group.key}}</h4>
    </div>
</div>

很明显,这是我的@Pipe.

@Pipe:

import { PipeTransform, Pipe } from '@angular/core';
import { isNullOrUndefined } from 'util';

@Pipe({name: 'keysCheckDisplay'})
export class KeysCheckDisplayPipe implements PipeTransform {
    transform(value, args: string[]): any {
        let keys = [];
        for (let key in value) {
            if (!isNullOrUndefined(value[key])) {
                let display = false;
                for (let keyChild in value[key]) {
                    if (!isNullOrUndefined(value[key][keyChild]) && value[key][keyChild]['display'] === true) {
                        display = true;
                        break;
                    }
                }
                if (display === true) {
                    keys.push({key: key, value: value[key]});
                }
            }
        }
        return keys;
    }
}

在此@Pipe中,您可以看到我做了几件事:

In this @Pipe as you can see I do several things:

  • 遍历filterGroups对象
  • 检查对象中的每个组,是否存在具有display: true的子级.
  • Loop through the filterGroups object
  • Check for each group within the object if exists a child with display: true.

功能:

我希望此@Pipe遍历我的Object,并向我返回具有至少一个元素的过滤器组",其中的display: true .

I want this @Pipe to loop through my Objectand return me the 'filter groups' that have at least 1 element with display: true.

问题:

@Pipe正在获取filterGroups对象的第一个版本,并且忽略了这样的事实,即一旦我从服务器接收到数据,该对象就会更改.

The @Pipe is getting the first version of the filterGroups object, and is ignoring the fact that the object changes as soon as I receive the data from the server.

如果我修改filterGroups对象的初始值,则@Pipe可以正常工作.

The @Pipe works fine if I modify the initial values of the filterGroups object.

我尝试过的事情:

  • 研究,研究,研究
  • 我将@Pipe更改为inpure,但是由于糟糕的性能我讨厌此解决方案,而且它进入了无限循环.
  • 我也尝试过这种方法: *ngFor="let group of filterGroups | async | keysCheckDisplay". 但是它引发了以下错误:
  • Research, research, research
  • I changed the @Pipe to inpure, but I hate this solution because of awful performance and also it entered an infinite loop.
  • I have also tried this approach: *ngFor="let group of filterGroups | async | keysCheckDisplay". But it throwed the following error:

错误:InvalidPipeArgument:管道"AsyncPipe"的"[对象对象]"

Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'

可能的解决方案?

  • 修改@Pipe?

修改初始的object?

创建第二个@Pipe以遍历第一个Pipe的结果吗?

Create a second @Pipe to loop through the first Pipe's result?

我希望它是详细而清晰的,如果没有,请不要发表评论以询问更多详细信息,我将很乐意更新该帖子.

I hope it was detailed and clear, if not, please don't esitate to comment asking for more details and I will gladly update the post.

先谢谢您!

推荐答案

仅当数据更改时才调用纯管道.这意味着数据"是新的对象实例时.如果仅修改对象的内容,则Angular更改检测将无法将其识别为更改,也不会调用管道.

A pure pipe is only called when the data changes. This means when "data" is a new object instance. If only the content of the object is modified, then Angular change detection won't recognize it as change and won't call the pipe.

可能的方法

  • 使管道不纯净:通常对性能造成很大负担
  • 复制对象,例如:
var tmp = this.data; this.data = {}; Object.assign(this.data, tmp);

  • 在管道中添加其他参数并更新参数值
  • *ngFor="let item of data | myPipe:counter"
    

    // updated `data`
    // this.counter++;
    

    这篇关于收到数据后Angular2应用Pipe的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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