Dojo DnD: как получить доступ к вновь скопированному узлу по событию onDndDrop? - PullRequest
2 голосов
/ 27 октября 2009

Я работаю над кодом, подобным следующему.

01: var c1 = new dojo.dnd.Source('container1', {copyOnly:true}); // container1 is a div
02: var c2 = new dojo.dnd.Source('container2');                  // container2 is a div
03: var list = [];
04: for (var i = 0; i < 3; i++) { list.push( dojo.create('div') ); }
05: c1.insertNodes(false, list);
06: 
07: function checkDndCopy(nodes, target){
08:  dojo.forEach(nodes, function(node){ alert(node.id); } );
09: }
10: dojo.subscribe("/dnd/drop", function(){
11:   var mgr = dojo.dnd.manager();
12:   checkDndCopy(mgr.nodes, mgr.target);
13: });

Узлы, вставленные в c1 в строке 05, имеют идентификатор "dojoUnique1, donoUnique2, dojoUnique3". В случае перетаскивания узла от c1 до c2 вызывается событие onDndDrop и метод подписки определяется в строке 10-13.

Я ожидал, что вновь скопированный узел появится в узлах (например) в строке 08. Но это не так. Когда dojoUnique1 является целью перетаскивания, узлы в строке 08 содержат только dojoUnique1.

Я хочу изменить некоторые атрибуты вновь скопированных узлов по событию onDndDrop. Пожалуйста, позволь мне знать, как это реализуется.

Ответы [ 3 ]

1 голос
/ 28 октября 2009

Во-первых, как правило, старайтесь избегать использования тем DnD, особенно для локальных вещей & mdash; они громоздки в использовании, потому что к тому времени, когда ваша функция вызывается, параметры могут быть изменены или даже уничтожены другими процессорами (как вы уже обнаружили). Используйте локальные события и / или методы переопределения. Если вы хотите что-то сделать для вновь вставленных узлов, просто переопределите onDrop (или onDropExternal, или onDropInternal, если вы хотите обрабатывать только определенные отбрасывания).

Еще один полезный совет: новые вставленные узлы выделены.

Давайте закодируем это:

var c1 = new dojo.dnd.Source('container1', {copyOnly:true});
var c2 = new dojo.dnd.Source('container2');

// ...

// the decorator technique
function paintRed(source){
  var old_onDrop = source.onDrop;
  source.onDrop = function(){
    // we don't care about actual parameters
    // (we will pass them in bulk)
    // let's do a drop:
    old_onDrop.apply(this, arguments);
    // now all dropped items are inserted and selected in c2
    // let's iterated over all selected items:
    this.forInSelectedItems(function(item, id){
      // print the id
      console.log(id);
      // paint it red
      dojo.style(id, "color", "red");
    });
  };
}

// now let's decorate c2
paintRed(c2);
// now c2 paints all dropped nodes red

Если вы разрешаете переставлять списки и хотите вносить изменения только для внешних отбрасываний (например, от c1 до c2), вам следует переопределить onDropExternal. Код будет таким же.

Поскольку этот пример не опирается на оригинальные элементы, вы можете сделать это с темами, но вам может понадобиться дополнительный код, если вы хотите сделать это условно (например, для c2, но не для c1). Если вас не волнуют другие вещи, на самом деле это тоже довольно просто:

dojo.subscribe("/dnd/drop", function(source, nodes, copy, target){
  // warning: by the time this function is called nodes
  // can be copied/modified/destroyed --- do not rely on them!
  // but we don't need them here
  target.forInSelectedItems(function(item, id){
    // print the id
    console.log(id);
    // paint it red
    dojo.style(id, "color", "red");
  });
});
1 голос
/ 27 октября 2009

Я не уверен, если это единственный (и лучший) способ, но вы можете написать свой собственный создатель узла, чтобы переопределить удаление удаленного узла и аватара. Пример ниже расширяет ваш код и делает отброшенные узлы красными:

    var c1 = new dojo.dnd.Source('container1', {copyOnly:true }); // container1 is a div
    var c2 = new dojo.dnd.Source('container2', { creator: nodeCreator }  );   // container2 is a div

    function nodeCreator(item, hint) {
      var node = dojo.create("div", { innerHTML: item }); 
      if (hint != "avatar") {
        dojo.style(node, 'color', 'red');
      }
      return { node: node, data: item };
    }

Вы можете найти больше информации о написании собственных создателей здесь и в google

0 голосов
/ 30 октября 2009

Основываясь на способе использования собственного создателя, я обнаружил следующее.

var d;
d = dojo.doc.createElement('div');
var c01 = new dojo.dnd.Source(d, { 'copyOnly': true, 'accept': [], 'creator': myCreator});

var arr = [];
for(i=0; i<3; i++){ 
  d = dojo.create('div'); // dnd items
  // define contents and properties of d
  arr.push( d );
}
c01.insertNodes(false, divArr);

d = dojo.doc.createElement('div');
var c02 = new dojo.dnd.Source(d, { 'creator': myCreator});

function myCreator(item, hint){
  var node = dojo.doc.createElement('div');
  node.id = dojo.dnd.getUniqueId();
  var mgr = dojo.dnd.manager();
  // from dojo.dnd.manager(), it is possible to find which one to create 
  // the follwoing condition is just a sample
  if(hint != 'avatar' && 
     mgr.source && mgr.target // these are null when creating newly inserted one
     mgr.source.node && mgr.target.node // by inspecting these nodes, one can know
                                        // whether the item is newly copied one
  ){
    dojo.style(node, 'color', 'red');
    // one can get mouse position from mgr and set the node position
  }
  var copyItem = createCopyItem( item );
  dojo.place(copyItem, node, 'last');

  return { node: node, data: copyItem, type:[ /* what you want */ ] };
}

Функция createCopyItem () выходит за рамки. Необходимо скопировать item и изменить новый объект, поскольку item нельзя поместить как в исходный parentNode, так и в node, созданный в myCreator ().

...