2015-09-15 15 views
8

Sto utilizzando Dragula per creare un insieme di componenti di trascinamento in Ember. Trasmetto un elenco di elementi a un wrapper genitore che contiene più bucket trascinabili. Questo elenco di elementi viene inizialmente filtrato in modo da correggere gli elementi nel bucket corretto. Quindi Dragula è cablato in modo che gli oggetti possano essere trascinati e rilasciati. Quando si verifica un evento drop, cerco di aggiornare l'oggetto Ember sottostante. Ciò può causare la riapplicazione del filtro e il verificarsi di alcuni rendering. Il problema è che il DOM è stato manipolato da Dragula e non è lo stesso di come Ember pensa che dovrebbe essere e i nodi DOM scompaiono.Risoluzione della vista di Brace e di Dragula del DOM

Come posso ottenere che Ember e Dragula giochino bene quando entrambi pensano di possedere il DOM e la sua rappresentazione attuale? Ho provato a cancellare l'evento drop draggle e poi a lasciare che Ember impostasse i valori con un successo limitato.

dnd-wrapper/template.hbs

{{yield (action "register")}} 

dnd-wrapper/component.js

export default Ember.Component.extend({ 
    drake: null, 
    buckets: [], 
    items: [], 
    initDragula: Ember.on('willInsertElement', function() { 
    this.set('drake', window.dragula()); 
    }), 
    setupDragulaEvents: Ember.on('didInsertElement', function() { 
    this.get('drake').on('drop', (itemEl, destinationEl, sourceEl) => { 
     let dest = this.buckets.findBy('element', destinationEl); 
     let source = this.buckets.findBy('element', sourceEl); 
     let item = this.items.findBy('element', itemEl); 

     item.component.set('item.bucket', dest.component.get('value')); 
    }); 
    }), 
    actions: { 
    register(type, obj) { 
     if(type === 'bucket') { 
     this.get('drake').containers.push(obj.element); 
     this.buckets.pushObject(obj); 
     } 
     else { 
     this.items.pushObject(obj); 
     } 
    } 
    } 
}); 

dnd-bucket/template.hbs

<h2>bucket {{value}}</h2> 
<ul> 
    {{#each filteredItems as |item|}} 
    {{dnd-item item=item register=register}} 
    {{/each}} 
</ul> 

dnd-bucket/component.js

export default Ember.Component.extend({ 
    items: null, 
    registerWithWrapper: Ember.on('didInsertElement', function() { 
    this.register('bucket', { 
     component: this, 
     element: this.$('ul')[0] 
    }); 
    }), 
    filteredItems: Ember.computed('[email protected]', function() { 
    return this.get('items').filterBy('bucket', this.get('value')); 
    }) 
}); 

dnd-item/template.hbs

{{item.title}} 

dnd-item/component.js

export default Ember.Component.extend({ 
    registerWithWrapper: Ember.on('didInsertElement', function() { 
    this.register('item', { 
     component: this, 
     element: this.$()[0] 
    }); 
    }) 
}); 

Demo online: http://ember-twiddle.com/c086d2853a926c310a23

GitHub Demo: https://github.com/RyanHirsch/dragula-ember-example

risposta

2

Ho incontrato lo stesso problema si sta descrivendo. Ho passato ore a provare cose diverse per risolverlo, e penso di aver finalmente trovato una soluzione hacky ma praticabile. La cosa importante è che ho dovuto forzare il bucket 'source' per rerenderne gli oggetti dopo aver attivato l'evento drop.

Sfortunatamente ho dovuto usare la forza bruta per far funzionare il rerendering, chiamare il rerender su nessuna delle viste genitore non funzionava. Ember pensa che gli oggetti che sono scomparsi dal DOM siano ancora lì e resi correttamente.

Ho finito con il wrapping dell'elenco filteredItems nel modello dnd-bucket con {{#if listVisible}}{{/if}}. Se si imposta quindi itemsVisible false e true, l'elenco viene forzato a eseguire il rerender e riparare il danno del DOM. Dovevo anche assicurarmi che questi set fossero prima e dopo il rendering nel runloop.

resetView: function() { 
    Ember.run.scheduleOnce('render', this,() => { 
    this.set("listVisible", false); 
    }); 
    Ember.run.scheduleOnce('afterRender', this,() => { 
    this.set("listVisible", true); 
    }); 
} 

Nel mio caso ho attivato resetView dopo aver aggiornato i modelli nel callback di rilascio. Sebbene questa correzione sia hacky, il risultato visivo è accettabile. Se gli elementi DOM sono spariti, vengono rimpiazzati, un po 'stridenti. Ma per il 99,9% del tempo in cui nessun elemento DOM è scomparso, non ci sono affatto difetti visivi.

+0

Avete un demo repo di questo funzionamento? Sto usando https://github.com/RubaXa/Sortable e causa problemi. Sto cercando di cambiare – tr3online