2016-12-07 74 views
8

使用ng2-dragula。我正在使用新的刪除訂單更新數據庫中每個項目的orderNumber。Angular 2 Dragula模型更新不正確

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

它返回的新型號訂單不反映包內的訂單。

TL; DR:有沒有人使用ng2-dragula在Drop數據庫中實現重新排序?

+0

有同樣的問題,似乎無法找到答案。我實際上丟失了一旦我放棄它就完全拖動的DOM元素。簡單地刪除'[dragulaModel] ='myList'似乎可以修復這種奇怪的行爲(仍然可以拖放 - 但不再可以觸發dragulaService.dropModel調用)。 –

+0

@DanJ,我看到的只是一個設置場景,onDrop或從onDrop返回的模型沒有任何關係? –

+0

對不起,一定是一個複製粘貼問題 - 繞圈試圖找出問題。 –

回答

5

如果你希望能夠拖動物品(沒有他們消失)和火災的dropModel事件:

  • 放入父元素的[dragula]和[dragulaModel]指令。 (例如,違背當前的doc在那裏說:把他們在<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 
} 
+1

謝謝,但我已經到了這個階段 - 我的問題是由onDrop返回的對象模型是錯誤的順序。我相當肯定這是對圖書館的限制,因爲丟棄的對象移動到正確的索引,但其他的只向下移動,而不是重新排序。這對於找到新插入的插槽是非常有用的,但是我需要在列表中替換**每個**項目的orderNumber –

+0

這是一個很好的討論,可以幫助其他人,並且還包含指向plunk的鏈接,顯示在dropModel事件觸發後使用dropModel對項目進行排序並捕獲正確的順序。 https://github.com/valor-software/ng2-dragula/issues/306 – rmcsharry

2

我終於找到了解決辦法。 我有一個水平列表。前兩個元素是我想要忽略的元素,它們都具有CSS類別ignore。所有元素都有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; 
} 
1

我發現馬薩爾的回答令人難以置信的幫助,甚至擴大了它一點點地更新發布到我的數據庫更新每個序列值項目(在我的情況下是一個組織內的聯繫人)在列表中:

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

希望這可以讓我更清楚地知道這個問題,與其他地方的其他人相似。

3

我正在使用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 
    } 
}