<ul class="questions"> <li> <div class="question" id="id1"> <span class="text"> , </span> <span class="edit">edit</span> </div> </li> </ul>
<ul class="questions"> <li> <div class="question" id="id1"> <input type="text" name="title" value=" , "> <span class="save">save</span> </div> </li> </ul>
$('.questions').on('click', '.save', function() { var $li = $(this).closest('li'); saveData($li); }); function saveData($li) { var $item = $li.children('.question'), id = $item.id, $input = $item.children('input'); $.ajax({ type: 'POST', url: '/save', dataType: 'json', data: $input.serialize(), success: function(response) { if ( ! response.errors) { $li.replaceWith(response.data); } } }); }
<ul class="questions"> <li> <div class="question" id="id2"> <span class="text"> </span> <span class="edit">edit</span> </div> <ul> <li> <div class="note" id="id1"> <span class="text">1 </span> <span class="edit">edit</span> </div> </li> <li> <div class="note" id="id2"> <span class="text">2 </span> <span class="edit">edit</span> </div> </li> </ul> </li> </ul>
$('.question').on('click', '.save', function() { saveData.call(this); }); function saveData() { // this ( , ) var self = this, // / $button = $(this), $item = $button.closest('div'), $li = $item.closest('li'), // id = $item.attr('id').replace(/[^0-9.]/g, ""), inputs = $item.find(':input'), type = $item.attr('class'); // ( ) return $.Deferred(function() { var def = this; $.ajax({ type: 'POST', url: '/save', dataType: 'json', data: inputs.serialize() + '&id=' + id + '&type=' + type, beforeSend: function(xhr){ // , .ignore // .ignore , // ( // ) var $inner_notes = $li.find('ul .save').not('.ignore'); // .. if($inner_notes.length) { // var deferreds = []; $inner_notes.each(function() { // , // this .save deferreds.push(saveData.call(this)); }); // $.when.apply(null, deferreds).always(function() { // - . // self .save saveData.call(self); }); // xhr.abort(); } }, success: function(response){ if ( ! response.errors) { // , $li.replaceWith(response.data); } else { // , $button.addClass('ignore'); } }, error: function() { // , $button.addClass('ignore'); } }).complete(function() { // - resolve() def.resolve(); }); }); }
// saveData: function() { var self = this, $button = $(this), $item = $button.closest('div'), $li = $item.closest('li'); } // $('.question').on('click', '.save', function() { saveData.call(this); }); // var $inner_notes = $li.find('ul .save').not('.ignore'); $inner_notes .each(function() { deferreds.push(saveData.call(this)); }); // saveData: function() { var self = this; .... $.when.apply(null, deferreds).always(function() { saveData.call(self); }); }
var deferreds = []; $children_notes.each(function() { deferreds.push(app.saveData.call(this)); }); $.when.apply(null, deferreds).always(function() { saveData.call(self); });
saveData: function() { ... return $.Deferred(function() { var def = this; ... $.ajax({...}).complete(function() { def.resolve(); }); } }
return $.Deferred(function() { var def = this; $.ajax({...}).complete(function() { def.resolve(); }); });
// function someFunc(){ // var def = $.Deferred(); setTimeout(function(){ // def.resolve(); }, 1000); // return def.promise(); } function someFunc(){ // return $.Deferred(function() { var def = this; setTimeout(function(){ // def.resolve(); }, 1000); })/* .promise() */; // , .promise() , deferred . } //someFunc.done(function() {});
beforeSend: function(xhr){ xhr.abort(); }
$.when.apply(null, deferreds).always(function() { saveData.call(self); });
var $inner_notes = $li.find('ul .save')/*.not('.ignore')*/; // .not() if($inner_notes.length) {}
<ul class="questions"> <li> <div class="question" id="id3"> <span class="text"> c </span> <span class="edit">edit</span> </div> <ul> <li> <div class="note" id="id1"> <span class="text">1 </span> <span class="edit">edit</span> </div> </li> <li> <div class="note" id="id2"> <span class="text">2 </span> <span class="edit">edit</span> </div> <ul> <li> <div class="note" id="id4"> <span class="text">4 </span> <span class="edit">edit</span> </div> <ul> <li> <div class="note" id="id7"> <span class="text">7 </span> <span class="edit">edit</span> </div> </li> <li> <div class="note" id="id8"> <span class="text">8 </span> <span class="edit">edit</span> </div> </li> </ul> </li> <li> <div class="note" id="id5"> <span class="text">5 </span> <span class="edit">edit</span> </div> <ul> <li> <div class="note" id="id6"> <span class="text">6 </span> <span class="edit">edit</span> </div> </li> </ul> </li> </ul> </li> <li> <div class="note" id="id3"> <span class="text">3 </span> <span class="edit">edit</span> </div> </li> </ul> </li> </ul>
var $inner_notes = $li.find('ul .save').not('.ignore')
// beforeSend , - getClosestChildrens saveData: function() { .... beforeSend: function(xhr){ var $inner_notes = $li.find('ul .save').not('.ignore'), // $children_notes = getClosestChildrens($inner_notes); if($children_notes.length) { var deferreds = []; $children_notes.each(function() { deferreds.push(app.saveData.call(this)); }); // $.when.apply(null, deferreds).always(function() { // // , . // self . app.saveData.call(self); }); // / xhr.abort(); } }, .... } // ( ). // // , . // .. " ", . function getClosestChildrens($inner_notes) { var children_notes = $.grep($inner_notes, function(value, key) { var is_child_of = false, $btn = $(value), $parent_li = $btn.closest('li'); $inner_notes.not($btn).each(function(key,v) { if($(this).closest($parent_li).length) { is_child_of = true; } }); return is_child_of ? false : true; }); return $(children_notes); }
Source: https://habr.com/ru/post/204456/
All Articles