html5 drag-and-drop knockout.js jquery-templates

¿Cómo usar HTML5 arrastrar y soltar en combinación con KnockoutJS?



drag-and-drop knockout.js (3)

Parece que no puedo enlazar a eventos de arrastrar y soltar en html5.

Aquí hay un ejemplo de una plantilla:

<script id="tabsTemplate" type="text/html"> <div class="dropzone" for="tab" data-bind="event:{dragover: function(event){event.preventDefault();}, dragenter: function(event){event.target.addClass(''dragover''); event.preventDefault();}, dragleave: function(event){event.target.removeClass(''dragover''); event.preventDefault();}} drop: function(event){console.log(''blahblah!'')}"></div> <h1 class="tab" draggable="true" data-bind="attr: {selected: $data.name === $item.selected()}, click: function(){$item.selected($data.name)}, event:{ dragstart: function(event){console.log(''blah!!'')}, dragend: function(event){document.getElementsByClassName(''dragover'')[0].removeClass(''dragover'')}}"> ${name} <img src="icons/close-black.png" class="close button" role="button" data-bind="click: function(e){$item.close($data)}"> </h1> </script>

Lo que tengo debería funcionar como se espera ... y lo hace siempre y cuando los haga normales en línea. Sin embargo, entonces los otros enlaces no funcionan!

Estoy recibiendo este mensaje de error:

Error de sintaxis no detectado: señal inesperada ''||'' jquery-tmpl.js: 10

¿Que está pasando aqui? ¿Hay algo que estoy haciendo mal?


Es posible que tenga el mismo problema que se menciona here , aunque se refiere a plantillas anidadas:

Advertencia

Si está pasando templateOptions al enlace de plantilla desde una plantilla anidada (por lo tanto, si especifica un enlace de plantilla desde dentro de una plantilla), preste especial atención a su sintaxis. Encontrarás un problema, si tu enlace se ve así:

<div data-bind="template: { name: ''items'', data: newItems, templateOptions: { header: “New Items!”}}"></div>

El complemento Plantillas jQuery se confunde con el}} al final de su enlace, ya que es parte de su sintaxis. Agregar un espacio entre sus llaves funcionará bien. Esperemos que esto evite a alguien un poco de frustración innecesaria.

<div data-bind="template: { name: ''items'', data: newItems, templateOptions: { header: “New Items!”} }"></div>


OK, lo he resuelto. Parece que faltaba en la documentación donde decía que en los nocauts, por defecto hace que todos los eventos eviten el incumplimiento / retorno falso. Así que todo lo que tenía que hacer era hacer que mi controlador dragstart se volviera verdadero, y ahora funciona. ¡¡Uf!!


Para aquellos (como yo) que necesitan un SSCCE trabajando; La sugerencia de la solución Follow [cybermotron], también soluciona un problema en el que los manejadores esperan datos y eventos de parámetros.

http://jsfiddle.net/marrok/m63aJ/

HTML

<script type="application/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <ul id="people" data-bind=''template: { name: "personTmpl", foreach: people }''> </ul> <div class="trash" data-bind ="visible:dragging, event:{ dragover: function(data, event){ event.preventDefault(); }, drop: function(data, event){ console.log(''trash'', $root.drag_start_index()) $root.trash($root.drag_start_index()) event.preventDefault(); } }"> <span>DELETE</span> </div> <script id="personTmpl" type="text/html"> <li class="draggable" draggable="true" data-bind="event:{ dragstart: function(data, event){ $(event.target).addClass(''dragSource'') $root.drag_start_index($index()); return $(event.target).hasClass(''draggable'');}, dragend: function(data, event){ $root.drag_start_index(-1); $(event.target).removeClass(''dragSource'') return true; }, dragover: function(data, event){event.preventDefault();}, dragenter: function(data, event){ $root.drag_target_index($index()); var element = $(event.target) if(element.hasClass(''draggable'')) element.toggleClass(''dragover''); event.preventDefault(); }, dragleave: function(data, event, $index){ var element = $(event.target) if(element.hasClass(''draggable'')) element.toggleClass(''dragover''); event.preventDefault(); }, drop: function(data, event){ $(event.target).removeClass(''dragover''); console.log(''swap'', $root.drag_start_index(), $root.drag_target_index() ) $root.swap($root.drag_start_index(), $root.drag_target_index()) } }"> <span data-bind=''text: name''></span> </li> </script>

Knockear

var Person = function(name) { this.name = ko.observable(name); }; var PeopleModel = function() { var self = this; self.drag_start_index = ko.observable(); self.drag_target_index = ko.observable(); self.dragging = ko.computed(function() { return self.drag_start_index() >= 0; }); self.people = ko.observableArray([ new Person("Oleh"), new Person("Nick C."), new Person("Don"), new Person("Ted"), new Person("Ben"), new Person("Joe"), new Person("Ali"), new Person("Ken"), new Person("Doug"), new Person("Ann"), new Person("Eve"), new Person("Hal")]); self.trash = function(index) { self.people.splice(index, 1) } self.swap = function(from, to) { if (to > self.people().length - 1 || to < 0) return; var fromObj = self.people()[from]; var toObj = self.people()[to]; self.people()[to] = fromObj; self.people()[from] = toObj; self.people.valueHasMutated() } }; ko.applyBindings(new PeopleModel());​