订购带有NG2-DRAGULA的物品清单

时间:2016-07-03 15:50:12

标签: angular dragula

我在循环中有一个项目列表。该数组最多有6个项目。

<div *ngFor="let item of items; let i=index">
<item-detail [item]="item" [dragula]='"first-bag"' [dragulaModel]='myItems' id="{{item.id}}" position={{i}}></item-detail>
</div>

我想要的输出是,当用户将项目拖放到另一个位置时,将执行API调用,新订单将保存在我的数据库中。

为了做到这一点,我需要物品ID和新位置。该位置必须是1到6之间的数字(基于用户拖动项目的位置..)

到目前为止我所做的是以下方法:

private onDrop(args) {
    let [e, el] = args;
    console.log(el.id)
    console.log(el.position)
  }

但ID和位置无法正常工作..我确信有一种更简单,更简单,更正确的方法。

有什么想法吗?

2 个答案:

答案 0 :(得分:5)

您需要在项目的父容器中移动dragula指令,如下所示:

PendingIntent

在yourComponent.ts

<div class="container" [dragula]='"bag-one"' [dragulaModel]='items'>
  <div [attr.id]="item.id" [attr.title]="i" class="card-item" *ngFor="let item of items; let i=index">
    <item-detail></item-detail> 
  </div>
</div>

您还可以在Item-Detail组件中使用@Input输入所需的ID和位置。

let [el, target, source] = args;
console.log(el.id);
console.log(el.title);

在你的Component.ts

<item-detail [iteminfo]="item"></item-detail>

这是我在我的项目中所做的。对于我的父组件:

Import {Component, Input} from '@angular/core';
  @Component({....});
  @Input() iteminfo: Item;

对于项目组件:

import { Component, Input } from '@angular/core';
import { Card } from '../model/card';
import { Item } from '../model/item';
import { dragula, DragulaService } from 'ng2-dragula/ng2-dragula';

@Component({
  selector: 'card', //parent component for item component
  template: ` 
    <div class="items"[dragula]='"bag-one"' [dragulaModel]='card.items'>
          <div class="card-item" *ngFor="let item of card.items; let i = index; trackBy item?.item_Id">              
              <item [item]="item" [index]="i"></item>
          </div>
    </div>

})
export class CardComponent {

  constructor(private dragulaService: DragulaService)
  {
    dragulaService.setOptions('bag-one', {
      revertOnSpill: true
    });
    dragulaService.drop.subscribe((value) => {
      this.onDrop(value.slice(1));
    });
  }
}

最后注意:请参阅&#34;使用setter拦截输入属性更改&#34;在CookBook下的angular.io网站 - &gt;组件互动https://angular.io/docs/ts/latest/cookbook/

答案 1 :(得分:1)

我知道这已经有一段时间了......但是我用这样的东西非常努力地挣扎,希望其他人能从我的想法中受益:

我的HTML:

&#13;
&#13;
<tbody [dragula]='"bag-one"' [dragulaModel]="currentWorkingData" #bag1>
  <tr *ngFor="let faq of currentWorkingData; let i = index;" class="faq" [attr.data-id]="faq.id" [attr.data-index]="i" [attr.data-title]="faq.title" [attr.data-description]="faq.description">
    <td>
      <span>{{ faq.title }}</span>
    </td>
  <td>
    <button (click)="removeFaq(faq)" class="btn btn-xs btn-danger">Remove</button>
    <br />
    <button (click)="editFaq(faq)" class="btn btn-xs btn-info">Edit</button>
    </td>
  </tr>
</tbody>
&#13;
&#13;
&#13;

在我的组件(打字稿)中,我有以下内容:

&#13;
&#13;
export class CategoriesComponent {
  categoryList: any = [];
  url: string = '';
  updatedCategory: any = [];

  constructor(private apiService: ApiService, private dragulaService: DragulaService) {
    let currentCategory = this.categoryList;
    this.url = apiService.urls.categories;
    
    apiService.get(apiService.urls.categories).subscribe(
      data => this.loadCategories(data),
      err => this.loadCategories('err'));


    dragulaService.setOptions('bag-one', {
      revertOnSpill: true
    });

    dragulaService.drag.subscribe((value: any) => {
      let currentCategory = this.categoryList; //onchage event ---> pushing data through
    });

    dragulaService.drop.subscribe((value: any[]) => { //runs when item being dragged is dropped into new location
      let currentCategory = this.categoryList; // --> pushing the data through
      const [bagName, e, el] = value;
      this.onDrop(value.slice(1)); //  --> passing to onDrop
    });
  }


  private onDrop(args: any) {
      let [el, target, source] = args;
      const rowData = Array.from(target.children);
      this.updatedCategory = rowData.map((row: any, index: number) => {
        return {
          id: row.dataset.id,
          name: row.dataset.name,
          sideBar: row.dataset.sidebar,
          index
        }
      });
      return new Promise((resolve: any, reject: any) => {
        this.handleSaveRequest();
      });
  }


  loadCategories(res:any) {
    if(res === 'err'){
        swal('Ooops!', 'Something went wrong, prease try again.', 'error');
    } else {
        console.log(res); //returns the current (correct) array
        for (let i = 0; i < res.categories.length; i++) {
          this.categoryList.push({
            id: res.categories[i].id,
            value: res.categories[i].name,
            sideBar: res.categories[i].sideBar,
            index: res.categories[i].index
          });
        }
    }
  }
&#13;
&#13;
&#13;

第一次执行此操作时,您必须手动将索引编号循环到其中,以便它具有初始值(或在保存到数据库时设置它)。

然后,当你拖放一些东西时^^^ ondrop方法也会在同一个组件(typescript)中运行一个handleSave方法...... 对我来说,我循环浏览页面上的当前值。我认为这是最好的方式,因为你一次推动几件事情(虽然,我没有javascript专家):

&#13;
&#13;
handleSaveRequest(): Promise < any > {
      const listCatArrange = this.updatedCategory;
      const { name, sideBar, id, index } = this.categoryList;
      let side_bar = sideBar;
      const bodyCL = { name, side_bar, index };
      return new Promise((resolve: any, reject: any) => {
          let i = 0;
          let processRequest = () => {
            if(i < listCatArrange.length){
              let bodyList = {
                name: listCatArrange[i].name,
                sideBar: listCatArrange[i].sideBar,
                index: listCatArrange[i].index
              };
              let url = this.apiService.urls.categories;
              let curId = listCatArrange[i].id;
              this.apiService.patch(url + `/${curId}`, bodyList).subscribe(
                data => processRequest(),
                err => resolve('err'),
              );
              i++;
              processRequest();
            } else{
              resolve(true);
            }
          };
          processRequest();
      });
  }
&#13;
&#13;
&#13;

我希望这可以帮助那些人。我花了很长时间与朋友一起解决这个问题。关于如何做这样的事情的牵引文件肯定没有很多。