我正在使用Angular8拖放,遇到了一些问题
我的概念是什么,我在做什么
我正在使用下面的JSON数据结构(如下所示),该结构通过moveItemInArray
和transferArrayItem
函数进行了更新
trucks = [{
"..": '',
"Deliveries": [{
"..": '',
"Packages": [{
}, {}, {}, ....]
}, {}, {}, ....]
}, {}, {}, ....]
一切正常,但是我需要通过拖放操作应用一些额外的东西
我希望将包裹直接放入卡车中...因此,当包裹直接放入卡车中时,我想在该卡车的运送中添加一个运送对象,然后在该运送中,我要分配放置包
我希望将交货直接放置在交货范围内...因此,当直接下降交货时,我想将以前交货的所有包装都移至当前交货
我已经尝试了很多不同的方法,但是拖放操作会受到干扰并且错过了行为
下面是我的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>
答案 0 :(得分: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.交货交货
if type of event.container.data === delivery and type of event.previousContainer === delivery
for each package from delivery add package to new delivery
好像您可以使用打字稿instanceof
一样。 https://www.typescriptlang.org/docs/handbook/advanced-types.html#instanceof-type-guards