当对象属性发生更改时,更改对ondrop事件的检测

时间:2018-02-08 18:36:52

标签: angular

我正在构建一个拖放界面,并认为我需要实现更改检测才能使其正常工作。

我的组件如下所示:

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { GetStoryFunnelService } from '../../services/get-story-funnel.service';

@Component({
  selector: 'app-funnel-grid',
  templateUrl: './funnel-grid.component.html',
})
export class FunnelGridComponent implements OnInit {

    results: any;

    columnNames = [
        {id: 0, name: 'Opened', items: []},
        {id: 1, name: 'Responded', items: []},
        {id: 2, name: 'Material requested', items: []},
        {id: 3, name: 'Material sent', items: []},
        {id: 4, name: 'Interview requested', items: []},
        {id: 5, name: 'Interview completed', items: []},
        {id: 6, name: 'Follow up sent', items: []},
        {id: 7, name: 'Follow up responded', items: []},
        {id: 8, name: 'Article secured', items: []},
        {id: 9, name: 'Article published', items: []},
        {id: 10, name: 'Not interested', items: []}
    ];

    constructor(
        private cdRef: ChangeDetectorRef,
        private getFunnel: GetStoryFunnelService
    ) { }

    ngOnInit() {
        this.getFunnel.getStoryFunnel().subscribe(data => {
            this.results = data;
            console.log(this.results);
        });
    }

    onItemDrop(event: any) {
        alert('dropped');
        const dropId = event.nativeEvent.srcElement.id;
        const dropItem = event.dragData;
        const index = this.results.findIndex(item => {
            return item.contactId === dropItem.contactId;
        });
        this.results[index].storyFunnelStatusId = dropId;
        this.cdRef.detectChanges();
        console.log(this.results[index]);
    }

}

当调用onItemDrop()函数时,它首先得到它被放入的元素的id,然后获取被删除的项的对象属性,然后我找到该对象在根results对象中,最后我更新了属性。然后在我的视图中使用storyFunnelStatusId来确定result项与哪个列相关联。

我遇到的问题是,当属性值更改时,视图不会更新。经过一些研究后我得知这是因为我必须手动启动变更检测。不幸的是我之前从未做过这样的事情所以我不确定实现这个的最好方法吗?

编辑:结果对象看起来像这样:

[
    {
        "contactId": 0,
        "contactName": "John Doe",
        "mediaOutletName": "Gadget",
        "pitchingInitiativeId": 0,
        "statusHistory": [
            {
                "completedDate": "2018-02-07T03:45:19.811Z",
                "storyFunnelId": 0,
                "storyFunnelStatusId": 0
            }
        ],
        "storyFunnelId": 0,
        "storyFunnelStatusId": 0,
        "updatedDate": "2018-02-07T03:45:19.811Z",
        "userId": 0
    }
]

编辑:模板视图

<div class="board-container">
    <div class="board-column" *ngFor="let column of columnNames">
        <div class="board-heading">
            {{ column.name }}
            <span class="count">4</span>
        </div>
        <div id="{{ column.id }}"
            class="board-body h-100"
            (onDrop)="onItemDrop($event)"
            droppable>
            <div class="card bg-light-blue mb-2" *ngFor="let item of (results | groupBy: column.id)" [dragData]="item" draggable>
                <div class="card-body">
                    <div class="card-title mb-0">
                        <h6>
                            <span class="text-primary"><strong>{{ item.contactName }}</strong></span>
                            <span class="text-secondary">- {{ item.mediaOutletName }}</span>
                        </h6>
                        <button class="btn btn-transparent p-0">
                            <small><i class="fa fa-caret-down p-0"></i></small>
                        </button>
                    </div>
                    <div class="card-text text-dark">
                        Sent: {{ item.updatedDate | date }}
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

编辑自定义管道

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

@Pipe({
    name: 'groupBy'
})

export class GroupByPipe implements PipeTransform {

    transform(items: any, groupId: number ): any {
        if (items instanceof Array) {
            return items.filter(items => items.storyFunnelStatusId === groupId);
        }
    }

}

1 个答案:

答案 0 :(得分:0)

根据上述评论,试试这个,

onItemDrop(event: any) {
        alert('dropped');
        const dropId = event.nativeEvent.srcElement.id;
        const dropItem = event.dragData;
        const index = this.results.findIndex(item => {
            return item.contactId === dropItem.contactId;
        });
        this.results[index].storyFunnelStatusId = dropId;
        this.results = [ ...this.results ]; // creating a new array reference and assigning to itself using the spread operator
        this.columnNames = [ ...this.columnNames ];
        this.cdRef.detectChanges();
        console.log(this.results[index]);
}