【问题标题】:Order a list of items with NG2-DRAGULA使用 NG2-DRAGULA 订购物品清单
【发布时间】:2016-07-03 15:50:12
【问题描述】:

我有一个循环中的项目列表。该数组最多有 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 和位置无法正常工作。我确信有一种更简单、更简单且正确的方法来执行此操作。

有什么想法吗?

【问题讨论】:

  • 得到了关于这个的任何答案???
  • 如果是这样,请发布您的解决方案。

标签: angular dragula


【解决方案1】:

您需要像这样在项目的父容器中移动 Dragula 指令:

<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>

在你的Component.ts中

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

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

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

在您的 Component.ts 中

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));
    });
  }
}

对于项目组件:

import { Component, Input } from '@angular/core';
import { Item } from '../model/item';

@Component({
  selector: 'item',
  template: `
    {{item.title}} {{index}}
  `
})
export class ItemComponent implements OnInit {
    constructor(private itemSvc:ItemService) {}

  private _index: number;

  @Input()item: Item;

  @Input()
    set index(i: number) {
    this._index = i;
    // Do something here like save to database.
    console.log('item index changed: ', this.item.title + i);
  }
  // Getter for the index Input property
  get index(): number{
    return this._index;
  }

}

最后说明:请参阅 angular.io 网站上 CookBook 下的“使用 setter 拦截输入属性更改” -> 组件交互 https://angular.io/docs/ts/latest/cookbook/

【讨论】:

    【解决方案2】:

    我知道这是很久以前的事了......但我非常努力地完成了类似这样的事情,希望其他人会从我的发现中受益:

    我的html:

    <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>

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

    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
              });
            }
        }
      }

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

    然后,当您拖放某些东西时 ^^^ ondrop 方法也会在同一个组件(打字稿)中运行一个 handleSave 方法... 对我来说,我循环浏览了页面上的当前值。我认为这确实是最好的方法,因为您一次要完成几件事(不过,我不是 javascript 专家):

    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();
          });
      }

    我希望这对那里的人有所帮助。我花了很长时间才和朋友一起解决这个问题。关于如何做这样的事情的 Dragula 文档肯定没有很多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      • 2011-04-09
      相关资源
      最近更新 更多