2012-05-04 4 views
7

Ich habe eine Standardvorlage in einer HTML-Datei wie:Wie wird JQuery .draggable() auf von Templates erstellten Elementen ausgelöst?

<template name="cards"> 
    {{#each all_cards}} 
    {{> card_item}} 
    {{/each}} 
</template> 
<template name="card_item"> 
    <div class="card" style="left:{{position.x}}px; top:{{position.y}}px"> 
    {{title}} 
    </div> 
</template> 

Ich möchte die Karten (CSS-Selektor .card) werden mit JQuery ziehbar haben. Jetzt seit Meteor automatisch aktualisiert das DOM mit der Vorlage, wann und wie kann ich wissen, wo. Draggable() auf was?

EDIT: Das ist so weit meine Lösung, die auf anderer Client sichtbar mit einer Taumel Animation (mit CSS3) anstehenden Bewegungen macht:

Template.card_item.events = { 
'mouseover .card': function (e) { 
    var $target = $(e.target); 
    var $cardContainer = $target.hasClass('card') ? $target : $target.parents('.card');  
    $cardContainer.draggable({containment: "parent", distance: 3}); 
}, 
'dragstart .card': function (e) { 
    Session.set("dragging_id", e.target.id); 
    $(e.target).addClass("drag"); 
    pos = $(e.target).position(); 
    Events.insert({type: "dragstart", id:e.target.id, left: pos.left, top: pos.top});  
}, 
'dragstop .card': function (e) { 
    pos = $(e.target).position(); 
    Events.insert({type: "dragstop", id:e.target.id, left: pos.left, top: pos.top});   
    Cards.update(e.target.id, {$set: {left:pos.left, top:pos.top}}); 
    Session.set("dragging_id", null); 
} 
} 

Events.find().observe({ 
added: function(event) { 
    if (event.type == "dragstart" && !Session.equals("dragging_id", event.id)) { 
     $("#"+event.id).draggable({disabled: true}); 
     $("#"+event.id).addClass("wobble");    
    } 
    if (event.type == "dragstop" && !Session.equals("dragging_id", event.id)) { 
     $("#"+event.id).animate({left: event.left, top: event.top}, 250);   
     Events.remove({id:this.id}); 
     $("#"+event.id).draggable({disabled: false}); 
    } 
} 
}); 
+1

Verwenden Sie 'Meteor.defer', es ist nicht in der Dokumentation, aber diese Frage erklärt es. Ich verwende es, um eine Liste sortierbar im Moment zu machen, und es funktioniert gut. http://stackoverflow.com/questions/10109788/callback-after-the-dom-was-updated-in-meteo-js – lashleigh

+0

Danke, ich werde es überprüfen! - Cool das funktioniert thx haufen! –

+0

Prost, Sie sind herzlich willkommen. Außerdem habe ich gerade gelernt, dass meteor.defer nur ein Wrapper für setTimeout ist, tippe 'Meteor.defer' in die Konsole ohne Argumente um zu sehen, was ich meine. – lashleigh

Antwort

6

EDIT: Dieser Ansatz scheint nicht in den neuesten Arbeit Versionen von Meteor, z v0.5.0. Siehe meine comment unten.

Sieht so aus, als würden wir an ähnlichen Dingen arbeiten! Ich habe a working proof of concept for a simple Magic: The Gathering app. Hier ist, wie ich zur Zeit umgesetzt haben Schleppen:

In einem <head> Abschnitt in einem Ihrer HTML-Dateien, fügen Sie die jQuery UI-Skript:

<script src="jquery-ui-1.8.20.custom.min.js"></script> 

Dann in einer js-Datei, stellen Sie sicher, Elemente werden ziehbar Mouseover (Hinweis: dies ist nicht optimal auf Touchscreens, da es zwei Berührungen erfordert zu ziehen ... ich bin für eine bessere Touchscreen-Lösung Suche):

Template.card_item.events['mouseover .card, touchstart .card'] = function (e) { 
    var $target = $(e.target); 
    if (!$target.data('isDraggable')) { 
     $target.data('isDraggable', true).draggable(); 
    } 
}; 

Und schließlich übernimmt die drag and dragstop events:

var prevDraggedTime = 0 

Template.card_item.events['drag .card'] = function (e) { 
    // get the cardId from e 
    var now = new Date().getTime(); 
    var position; 

    if (now - prevDraggedTime > 250) { 
     position = $(e.target).position(); 
     Cards.update(cardId, {$set: {x: position.top, y: position.left}}); 
     prevDraggedTime = now; 
    } 
} 

Template.card_item.events['dragstop .card'] = function (e) { 
    // get the cardId from e 
    var position = $(e.target).position(); 
    Cards.update(cardId, {$set: {x: position.top, y: position.left}}); 
} 
+0

Ich glaube nicht, dass das Aktualisieren auf "Ziehen" eine gute Idee ist. Das könnte Hunderte von Updates für nur einen kleinen Widerstand sein. Aktualisieren Sie einfach auf Dragent und verwenden Sie eine CSS3-Transformation, um Dinge reibungslos auf anderen Clients zu bewegen. – lashleigh

+0

Ja, das war nur um das Konzept zu demonstrieren. In meinem aktuellen Code aktualisiere ich die Position auf "dragstop" und dann alle 250ms auf "drag". – Emmett

+0

Cool, das macht viel mehr Sinn. Ich denke, es wäre es wert, in Ihrer Antwort so viel zu sagen. – lashleigh

Verwandte Themen