16

使用 ng2-dragula。我正在寻找使用新删除的订单更新数据库中每个项目的 orderNumber。

dragulaService.dropModel.subscribe((value) => {
  var drake = dragulaService.find('bag-orders').drake
  var models = drake.models
  console.log(models)
})

它返回的新模型订单不反映包内的订单。

TL;DR:有没有人使用 ng2-dragula 在数据库 onDrop 中实现重新排序?

4

4 回答 4

12

如果您希望能够拖动项目(不让它们消失)并触发 dropModel 事件:

  • 将 [dragula] 和 [dragulaModel] 指令放在父元素中。(例如,与将它们放入的当前文档相反<li>,您必须将它们放入<ul>

  • 注入 dragularService,并在组件的构造函数中:

  • 为包调用 dragulaService.setOptions (你可以传递一个空字典)。如果您不调用它,dropModel则不会触发回调

  • 订阅 dropModel

结果:

<!--thecomponent.html-->
<h2>Playlists</h2>
<ul [dragula]='"first-bag"' [dragulaModel]='playlists'>
  <li *ngFor="let playlist of playlists">

//Inside the component.ts  
playlists: Playlist[];

constructor(private youtubeService: YoutubeService, private dragulaService: DragulaService) {

    dragulaService.setOptions('first-bag', {})
    dragulaService.dropModel.subscribe((value) => {
      this.onDropModel(value);
    });
}

private onDropModel(args) {
    //Here, this.playlists contains the elements reordered
}
于 2016-12-11T12:13:50.290 回答
8

我正在使用 ng2-dragula 并且我注意到的东西很奇怪。我遇到的问题是一样的。服务器调用未根据拖动顺序更新数据对象。

我刚刚在 ngDoCheck 生命周期钩子中使用了 if 子句来解决这个问题。

它在控制台的打印对象中排序。在深入挖掘之后,可以在网络中发现与更新服务器调用一起发送的对象是未更新的对象。

所以,这是因为服务器调用是在数据对象更新之前进行的。

我所做的只是添加一个可以跟踪拖动的全局变量已经更新了数据对象。

private dropModelUpdated = false;

ngAfterViewInit() {
    // this method only changes a variable to execute a method in ngDoCheck
    this.dragulaService.drop.subscribe((value) => {
      this.dropModelUpdated = true;
    });
}

然后,在 ngDoCheck 生命周期钩子中,

ngDoCheck() {    
    if (this.dropModelUpdated) { // this excutes if this.dropModelUpdated is true only
        const drake = this.dragulaService.find('any_bag_name').drake;
        const models = drake.models;
        this.modelContent.groups = models[0];
        // ...Here... Make the server or DB call to update the model with the changed/sorted order
        this.dropModelUpdated = false; // make sure this is there for the next smooth execution
    }
}
于 2017-07-20T07:28:17.900 回答
5

我终于找到了解决方案。我有一个水平列表。前两个元素是我想忽略的元素,并且都有ignoreCSS 类。并且所有元素都有item类。所以标记:

<ul [dragula]='"foo-list"' class="list">
    <li class="list ignore">a</li>
    <li class="list ignore">b</li>
    <li class="list" *ngFor="let item of getList()" [attr.data-id]="item.id">{{ item.name }}</li>
</ul>

然后是打字稿:

constructor(private dragulaService: DragulaService) {
    let dragIndex: number, dropIndex: number;

    dragulaService.setOptions('foo-list', {
        moves: (el, source, handle, sibling) => !el.classList.contains('ignore'),
        accepts: (el, target, source, sibling) => sibling === null || !sibling.classList.contains('ignore'),
        direction: 'horizontal'
    });

    dragulaService.drag.subscribe((value) => {
        // HACK
        let id = Number(value[1].dataset.id);
        if (!!id) {
            dragIndex = _.findIndex(this.getList(), {id: id});
        }
    });

    dragulaService.drop.subscribe((value:any[]) => {
        // HACK
        let elementNode = value[2].querySelectorAll('.item:not(.ignore)').item(dragIndex);
        if (elementNode) {
            let id = Number(elementNode.dataset.id);
            if (!!id) {
                dropIndex = _.findIndex(this.getList(), {id: id});
            }
        }

        if (value[2] === value[3]) { // target === source
            if (dragIndex >= 0 && dropIndex >= 0 && dragIndex !== dropIndex) {
                let temp: any = this.list[dragIndex];

                this.list[dragIndex] = this.list[dropIndex];
                this.list[dropIndex] = temp;
            }
        }

        // Custom code here
    });
}

getList(): any[] {
    return this.list;
}
于 2017-01-20T12:43:58.637 回答
2

我发现 Marçal 的回答非常有帮助,甚至对其进行了扩展,以将更新发布到我的数据库以更新列表中每个项目(在我的情况下是组织内的联系人)的序列值:

HTML(容器是联系人的组织。在我的情况下,联系人不能在组织之间移动):

<div class="container" [dragula]="'org-' + org.id" [dragulaModel]="org.contacts">
  <nested-contact *ngFor="let contact of org.contacts" [user]="contact" class="contact" [attr.data-id]="contact.id"></nested-contact>
</div>

JS(在我的联系人服务中,一个 PUT 函数用于更新与我的每个联系人关联的存储序列值,以便他们的订单持续存在):

contactsIdPut (id, body) {
  let url = '/api/v3/contacts/' + id + '?access_token=' + localStorage.getItem('access_token');
  let headers = new Headers({ 'Content-Type': 'application/json' });
  let options = new RequestOptions({ headers: headers });

  return this.http.put(url, body, options)
    .map((response: Response) => {
      return response.json();
    });

}

JS(在我的组织视图组件中,分别概述拖放时要执行的操作):

export class nestedOrganizationComponent {
  orgs = [];
  thisOrg: any;
  thisContact: any;

  constructor (private _contactService: ContactService, private dragulaService: DragulaService) {
    this._contactService = _contactService;

    let dragIndex: any;
    let dropIndex: any;
    let elementNode: any;

    dragulaService.drag.subscribe((value) => {
      let id = Number(value[1].dataset.id);
      let orgId: Number = value[0].split('-')[1];
      elementNode = value[2].querySelectorAll('.contact:not(.ignore)').item(dragIndex);

      if (!!id) {
        // this renderedOrgs is just an array to hold the org options that render in this particular view
        this._organizationService.renderedOrgs.push(this.org);
        this.thisOrg = this._organizationService.renderedOrgs.filter(org => { return org.id == orgId; })[0];
        this.thisContact = this.thisOrg.contacts.filter(contact => { return contact.id == id; })[0];

        let arr = this.thisOrg.contacts.map(x => { return x.id; });
        dragIndex = arr.indexOf(id);
      }
    });

    dragulaService.drop.subscribe((value: any[]) => {
      if (elementNode) {
          let id = Number(elementNode.dataset.id);
          if (!!id) {
            let arr = this.thisOrg.contacts.map(x => { return x.id; });
            dropIndex = arr.indexOf(id);
          }
      }

      if (value[2] === value[3]) { // target container === source container
          if (dragIndex >= 0 && dropIndex >= 0 && dragIndex !== dropIndex) {
            this.thisOrg.contacts.forEach((contact, index) => {
              contact.sequence = index;
              this.updateSequence(contact.id, index);
            });
          }
      }
    });
  }

  updateSequence (id: Number, index: Number) {
    let contactBody = {
      avatar: {
        sequence: index,
      }
    };

    return this._contactService.contactsIdPut(id, contactBody)
      .subscribe(
        (data: any) => {
          // nothing is needed, the same view can apply because the contact has already been moved.
        },
        (error: any) => {
          console.error(error);
        }
      );
  }
}

希望这可以在类似于我今天发现自己的地方向其他人提供更清晰的信息。

于 2017-03-29T03:41:46.263 回答