2016-12-07 8 views
8

Работа с ng2-dragula. Я ищу, чтобы обновить orderNumber для каждого элемента в базе данных, используя новый сброшенный порядок.Угловая 2 Модель Dragula неверно обновлена ​​

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

Новый заказ модели, который он возвращает, не отражает порядок в сумке.

TL; Кто-нибудь внедрил переупорядочение в базе данных onDrop с ng2-dragula?

+0

Имея тот же вопрос и не могу найти ответ. Я фактически теряю элемент DOM, который я перетаскиваю, когда я его бросаю. Просто удаление '[dragulaModel] = 'myList'' похоже исправить это странное поведение (все еще способное перетаскивать), но больше не может вызвать вызов dragulaService.dropModel). –

+0

@DanJ, ​​я вижу только сценарий установки, ничего о onDrop или модели, возвращенной из onDrop? –

+0

Извините, должно быть, была проблема с копией - кругом, пытаясь разобраться в проблеме. –

ответ

5

Если вы хотите, чтобы иметь возможность перетаскивать элементы (без их исчезновения) и огонь событие 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 
} 
+1

спасибо, но я дошел до этого этапа - моя проблема - это объектная модель, возвращаемая onDrop, находится в неправильном порядке. Я вполне уверен, что это ограничение библиотеки, так как выпавший объект перемещается к правильному индексу, а остальные только сдвигаются вниз, а не переупорядочиваются. Это было бы очень полезно найти в каком слоте новый, но мне нужно заменить ** каждый номер заказа ** в списке –

+0

Вот хорошее обсуждение, которое могло бы помочь другим, а также включить ссылку на плунжер, который показывает упорядочивание элементов с помощью 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

Я нашел ответ MarCal невероятно полезно, и даже расширил его немного после обновления к моей БД, чтобы обновить значение последовательности каждого (контакты в пределах организации, в моем случае) в списке:

HTML (container is the contact.контакт, в моем случае, не может перемещаться между организациями):

<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 используется жизненный цикл, чтобы решить проблему.

Он сортируется в напечатанном объекте в консоли. После более глубокого поиска в сети выяснилось, что объект, отправленный с вызовом сервера обновлений, был не обновлен.

Итак, это потому, что вызов сервера выполняется до обновления объекта данных.

Все, что я сделал, это добавление глобальной переменной, которая может отслеживать перетаскивание, обновила объект данных.

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