0

我正在使用 Angular8 拖放并遇到一些问题

我的概念是什么,我在做什么

  1. 我在其中拖放交货的卡车
  2. 我拖放包裹的交付工作正常

我正在使用以下 JSON 数据结构(如下所示),它使用moveItemInArraytransferArrayItem功能进行了更新

trucks = [{
    "..": '',
    "Deliveries": [{
        "..": '',
        "Packages": [{

        }, {}, {}, ....]
    }, {}, {}, ....]
}, {}, {}, ....]

一切正常,但我需要一些额外的东西来应用拖放,也就是说,

  1. 我希望将包裹直接放入卡车内......所以当包裹直接放入卡车时,我想在该卡车交付中添加一个交付对象,然后在该交付中,我想分配丢弃包

  2. 我希望将交付直接丢弃在交付中......所以当直接丢弃交付时我想将之前交付包的所有包裹移动到当前交付

我已经尝试了很多不同的东西,但是拖放会受到干扰并且错过行为

下面是我的 ts 和 HTML 模板代码

import { Component, Input, OnInit } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';

import { ModelTruck } from '../../core/models/model-truck';
import { ModelDelivery } from '../../core/models/model-delivery';
import { ModelPackage } from '../../core/models/model-package';

@Component({
    selector: 'app-manual',
    templateUrl: './manual.component.html',
    styleUrls: ['./manual.component.css']
})

export class ManualComponent implements OnInit {

    @Input() packages: ModelPackage[];
    @Input() trucks: ModelTruck[];
    @Input() deliveries: ModelDelivery[];

    /**
     * Trucks inside work area
     */
    workTrucks = [];

    /**
     * Deliveries drop inside trucks connected element IDs
     */
    truckIds = ['no-trucks'];

    /**
     * Packages drop inside deliveries connected element IDs
     */
    deliveryIds = ['no-delivery'];

    /**
     * Column from which we are applying filter
     */
    column: any = 'Km';

    /**
     * Direction use for filter ASC or DESC
     */
    direction = 1;

    /**
     * Choosed truck/delivery/package data
     */
    choosed = {
        '1': '-',
        '2': '-',
        '3': '-',
        '4': '-',
        '5': '-',
        '6': '-',
        '7': '-',
        '8': '-',
        '9': '-',
        '10': '-',
        '11': '-',
        '12': '-',
        '13': '-',
        '14': '-',
        '15': '-',
        '16': '-',
        '17': '-',
        '18': '-',
        '19': '-',
        '20': '-',
        '..': '..',
    };

    /**
     * Initializing constructor
     */
    ngOnInit() {

        this._createConnectedIds();
        this._calculateAllStuff();
    }

    /**
     * Creating connected link Ids for the drag and drop elements
     */
    _createConnectedIds() {

        // For the deliveries to be drag and drop
        for (let truck of this.trucks) {
            this.truckIds.push(`truck-${truck.ID}`);
            for (let delivery of truck.Deliveries) {
                this.deliveryIds.push(`delivery-${delivery.ID}`);
            }
        }

        // For the packages to be drag and drop
        for (let delivery of this.deliveries) {
            this.deliveryIds.push(`delivery-${delivery.ID}`);
        }
    }

    /**
     * Onchange sort by
     */
    doSort(sort) {
        this.direction = sort == 'ASC' ? 1 : -1;
    }

    /**
     * Onchange filter by
     */
    doFilter(filter) {
        this.column = filter;
    }

    /**
     * Event on drop the packages
     */
    onPackageDrop(event: CdkDragDrop<string[]>) {

        if (event.previousContainer === event.container) {
            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
        } else {
            transferArrayItem(event.previousContainer.data,
              event.container.data,
              event.previousIndex,
              event.currentIndex);
        }

        this._calculateAllStuff();
    }

    /**
     * Event on drop the deliveries
     */
    onDeliveryDrop(event: CdkDragDrop<string[]>) {

        if (event.previousContainer === event.container) {
            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
        } else {
            transferArrayItem(event.previousContainer.data,
              event.container.data,
              event.previousIndex,
              event.currentIndex);
        }

        this._calculateAllStuff();
    }

    /**
     * Event on drop the trucks
     */
    onTruckDrop(event: CdkDragDrop<string[]>) {

        if (event.previousContainer === event.container) {
            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
        } else {
            transferArrayItem(event.previousContainer.data,
              event.container.data,
              event.previousIndex,
              event.currentIndex);
        }

        this._calculateAllStuff();
    }

    /**
     * Calculate all the stuffs
     * Related to weight, volume, cost and number of packages etc
     */
    _calculateAllStuff() {

        this._removeDeliveriesWithoutPackage();
        this._calculateTrucksStuff();
        this._calculateDeliveriesStuff(this.deliveries);

        console.log('-----------------------');
        console.log('Trucks Inside The List');
        console.log(this.trucks);
        console.log('Trucks Inside Work Area');
        console.log(this.workTrucks);
    }

    /**
     * Remove deliveries without package
     */
    _removeDeliveriesWithoutPackage() {

        // Remove deliveries not contains package (Deliveries area)
        this.deliveries = (this.deliveries).filter(function(obj) {
            return obj.Packages.length != 0;
        });

        // Remove deliveries not contains package (Work Area)
        for( let truck of this.workTrucks ) {
            truck.Deliveries = (truck.Deliveries).filter(function(obj) {
                return obj.Packages.length != 0;
            });
        }
    }

    /**
     * Calculate package related stuffs
     * Related to weight, volume, cost and number of pieces etc
     */
    _calculatePackagesStuff(packages) {

        let packageStuffs = {
            ActualWeightDry: packages.filter((obj) => obj.TypePackage === 'dry').length,
            ActualWeightCold: packages.filter((obj) => obj.TypePackage === 'cold').length,
            ActualWeight: 0,
            ActualVolume: 0,
            ActualCostMerchandise: 0,
            NumberPackages: packages.length,
            NumberPieces: 0
        };

        for( let item of packages ) {
            packageStuffs.ActualWeight += item.ActualWeight;
            packageStuffs.ActualVolume += item.ActualVolume;
            packageStuffs.ActualCostMerchandise += item.ActualCostMerchandise;
            packageStuffs.NumberPieces += item.NumberPieces;
        }

        return packageStuffs;
    }

    /**
     * Calculate deliveries related stuffs
     * Related to weight, volume, cost and number of pieces etc
     */
    _calculateDeliveriesStuff(deliveries) {

        let deliveryStuffs = {
            MaxCostMerchadise: 0,
            ActualWeight: 0,
            ActualVolume: 0,
            NumberDestinations: deliveries.length,
            ActualCostMerchandise: 0,
            NumberPackages: 0,
            NumberPieces: 0,
            Trip: 0
        };

        for( let delivery of deliveries ) {
            deliveryStuffs.MaxCostMerchadise += delivery.MaxCostMerchadise;
            deliveryStuffs.ActualWeight += delivery.ActualWeight;
            deliveryStuffs.ActualVolume += delivery.ActualVolume;
            deliveryStuffs.ActualCostMerchandise += delivery.ActualCostMerchandise;
            deliveryStuffs.NumberPackages += delivery.Packages.length;
            deliveryStuffs.NumberPieces += delivery.NumberPieces;
            deliveryStuffs.Trip += delivery.Trip;

            let packageStuffs = this._calculatePackagesStuff(delivery.Packages);
            let keys = Object.keys(packageStuffs);
            for( let key of keys ) {
                delivery[key] = packageStuffs[key];
            }
        }

        return deliveryStuffs;
    }

    /**
     * Calculate trucks related stuffs for both work and in list
     * Related to weight, volume, cost and number of pieces etc
     */
    _calculateTrucksStuff() {
        this._calculateForTruck(this.trucks);
        this._calculateForTruck(this.workTrucks);
    }

    /**
     * Calculate truck stuff
     * Resulable code
     */
    _calculateForTruck(trucks) {
        for( let truck of trucks ) {
            let deliveryStuffs = this._calculateDeliveriesStuff(truck.Deliveries);
            let keys = Object.keys(deliveryStuffs);
            for( let key of keys ) {
                truck[key] = deliveryStuffs[key];
            }
        }
    }

    /**
     * Recalculating time
     */
    doRecalcTime() {
        alert('Doing recalculate time[need to implement]');
    }

    /**
     * Recalculating the order
     */
    doRecalcOrder() {
        alert('Doing recalculate order[need to implement]');
    }

    /**
     * Choosed element
     */
    choose(elem) {
        this.choosed = elem;
    }

    /**
     * Choosed element keys only
     */
    choosedKeys() {
        return Object.keys(this.choosed);
    }

    /**
     * Check if object
     */
    isItObject(elem) {
        return elem instanceof Object;
    }
}

<div class="main">
    <div class="width-20 truck-lists">
        <div class="sorting">
            <div class="sort-filters">
                <select (change)="doFilter($event.target.value)">
                    <option value="">Filter By</option>
                    <option value="TypeVehicle">TypeVehicle</option>
                    <option value="MaxWeight">MaxWeight</option>
                    <option value="MaxVolume">MaxVolume</option>
                    <option value="Km">Km</option>
                    <option value="Cost">Cost</option>
                </select>
            </div>
            <div class="asc-or-desc" (change)="doSort($event.target.value)">
                <select>
                    <option value="">Sort By</option>
                    <option value="ASC">ASC</option>
                    <option value="DESC">DESC</option>
                </select>
            </div>
        </div>
        <ul 
            cdkDropList 
            #truckArea="cdkDropList"
            [cdkDropListData]="trucks" 
            [cdkDropListConnectedTo]="[workArea]" 
            (cdkDropListDropped)="onTruckDrop($event)">
            <li 
                cdkDrag
                *ngFor="let truck of trucks | orderBy: {property: column, direction: direction}"
                class="truck-item"
                (click)="choose(truck)">
                <div class="truck-item-content">
                    {{ truck.TypeVehicle }} 
                    #{{ truck.ID }} | 
                    {{ truck.NumberDestinations }} Deliveries | 
                    {{ truck.NumberPackages }} Packages | 
                    {{ truck.Km }} Km | 
                    ${{ truck.Cost }}
                </div>

                <ol type="i">
                   <li *ngFor="let delivery of truck.Deliveries">
                       {{ delivery.State }}, {{ delivery.DestinationTR1 }}
                   </li>
                </ol>

                <span class="truck-size-tag">{{ truck.ID }}</span>
            </li>
        </ul>
    </div>
    <div class="width-60 truck-works">
        <div class="truck-works-dashboard">
            <ul 
                cdkDropList 
                #workArea="cdkDropList"
                [cdkDropListData]="workTrucks" 
                [cdkDropListConnectedTo]="[truckArea]"
                (cdkDropListDropped)="onTruckDrop($event)">
                <li 
                    cdkDrag
                    *ngFor="let truck of workTrucks"
                    class="truck-item truck-item-in-dashboard"
                    (click)="choose(truck)">
                    <div class="truck-item-content">
                        {{ truck.TypeVehicle }} 
                        #{{ truck.ID }} | 
                        {{ truck.NumberDestinations }} Deliveries | 
                        {{ truck.NumberPackages }} Packages | 
                        {{ truck.Km }} Km | 
                        ${{ truck.Cost }}
                    </div>
                    <div class="truck-row">
                        <div class="only-deliveries">
                            <ul 
                                cdkDropList 
                                [cdkDropListData]="truck.Deliveries" 
                                cdkDropListOrientation="horizontal" 
                                [cdkDropListConnectedTo]="truckIds" 
                                id="truck-{{ truck.ID }}" 
                                (cdkDropListDropped)="onDeliveryDrop($event)">
                                <li 
                                    cdkDrag
                                    *ngFor="let delivery of truck.Deliveries"
                                    class="delivery-item"
                                    (click)="$event.stopPropagation(); choose(delivery)">
                                    <div class="delivery-name">
                                        {{ delivery.State }} - {{ delivery.DestinationTR1 }}
                                    </div>
                                    <div class="delivery-time">
                                        {{ delivery.Delivery }}
                                    </div>
                                    <ul 
                                        cdkDropList 
                                        [cdkDropListData]="delivery.Packages" 
                                        [cdkDropListConnectedTo]="deliveryIds" 
                                        cdkDropListOrientation="horizontal"  
                                        (cdkDropListDropped)="onPackageDrop($event)" 
                                        id="delivery-{{ delivery.ID }}">
                                        <li 
                                            cdkDrag
                                            *ngFor="let package of delivery.Packages"
                                            [ngClass]="package.Type == 'Urgent' ? 'package-item urgent' : 'package-item'"
                                            (click)="$event.stopPropagation(); choose(package)">
                                            Pack #{{ package.ID }}<br>
                                            {{ package.Type }}
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </div>
                        <div class="only-dashboard">
                            <table>
                                <thead>
                                    <tr>
                                        <th>Restriction</th>
                                        <th>Kg</th>
                                        <th>m3</th>
                                        <th>$</th>
                                        <th>Access</th>
                                        <th>Minutes</th>
                                        <th>Incomp</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <th>Actual</th>
                                        <td>{{ truck.ActualWeight }}</td>
                                        <td>{{ truck.ActualVolume }}</td>
                                        <td>${{ truck.ActualCostMerchandise }}</td>
                                        <td>-</td>
                                        <td>-</td>
                                        <td>-</td>
                                    </tr>
                                    <tr>
                                        <th>Max</th>
                                        <td>{{ truck.MaxWeight }}</td>
                                        <td>{{ truck.MaxVolume }}</td>
                                        <td>${{ truck.MaxCostMerchadise }}</td>
                                        <td>-</td>
                                        <td>-</td>
                                        <td>-</td>
                                    </tr>
                                    <tr>
                                        <th>Available</th>
                                        <td>
                                            {{ truck.MaxWeight - truck.ActualWeight }}
                                        </td>
                                        <td>
                                            {{ truck.MaxVolume - truck.ActualVolume }}
                                        </td>
                                        <td>
                                            ${{ truck.MaxCostMerchadise - truck.ActualCostMerchandise }}
                                        </td>
                                        <td>-</td>
                                        <td>-</td>
                                        <td>-</td>
                                    </tr>
                                    <tr>
                                        <th>%Available</th>
                                        <td>-</td>
                                        <td>-</td>
                                        <td>-</td>
                                        <td>-</td>
                                        <td>-</td>
                                        <td>-</td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                    <span class="truck-size-tag">{{ truck.ID }}</span>
                </li>
            </ul>
        </div>
        <div class="no-truck-deliveries">
            <h4>No Truck</h4>
            <ul 
                cdkDropList 
                [cdkDropListData]="deliveries" 
                cdkDropListOrientation="horizontal" 
                [cdkDropListConnectedTo]="truckIds"
                (cdkDropListDropped)="onDeliveryDrop($event)" 
                id="no-trucks"
                class="no-truck">
                <li 
                    cdkDrag
                    *ngFor="let delivery of deliveries"
                    class="delivery-item"
                    (click)="choose(delivery)">
                    <div class="delivery-name">
                        {{ delivery.State }} - {{ delivery.DestinationTR1 }}
                    </div>
                    <div class="delivery-time">
                        {{ delivery.Delivery }}
                    </div>
                    <ul 
                        cdkDropList 
                        [cdkDropListData]="delivery.Packages" 
                        [cdkDropListConnectedTo]="deliveryIds" 
                        cdkDropListOrientation="horizontal"  
                        (cdkDropListDropped)="onPackageDrop($event)" 
                        id="delivery-{{ delivery.ID }}">
                        <li 
                            cdkDrag
                            *ngFor="let package of delivery.Packages"
                            [ngClass]="package.Type == 'Urgent' ? 'package-item urgent' : 'package-item'"
                            (click)="$event.stopPropagation(); choose(package)">
                            Pack #{{ package.ID }}<br>
                            {{ package.Type }}
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
    <div class="width-20 truck-datas">
        <div class="action-buttons">
            <button class="btn">Import</button>
            <button class="btn">Export</button>
        </div>
        <div class="element-datasets">
            <table>
                <tr *ngFor="let key of choosedKeys()">
                    <th [hidden]="isItObject(choosed[key])">{{ key }}</th>
                    <td [hidden]="isItObject(choosed[key])">{{ choosed[key] }}</td>
                </tr>
            </table>
        </div>
        <div class="action-buttons">
            <button class="btn" (click)="doRecalcTime()">Recalculate Time</button>
            <button class="btn" (click)="doRecalcOrder()">Recalculate Order</button>
        </div>
    </div>
</div>

4

1 回答 1

0

我认为您应该根据event.container.data.

所以对于1. 一个包裹直接扔到卡车里面

在伪代码中:

if type of event.container.data === package and type of event.previousContainer is === truck

   Add package to delivery then add delivery to truck

而对于 2. Delivery in Delivery

if type of event.container.data === delivery and type of event.previousContainer === delivery

   for each package from delivery add package to new delivery

看起来像是你可以使用 Typescriptsinstanceof的东西。https://www.typescriptlang.org/docs/handbook/advanced-types.html#instanceof-type-guards

于 2019-08-21T12:18:52.620 回答