2016-07-14 2 views
0

Я пытаюсь переключить диапазон, содержащий анимацию загрузки, нажимать кнопку до тех пор, пока функция не завершится с помощью v-if. Но когда я нажимаю кнопку, DOM зависает, и элемент span остается неизменным до тех пор, пока не закончится вызов функции. Как я могу заставить DOM не замораживать и значок загрузки показывать? Неблокирующее нажатие кнопки может быть решением?Vue js button freezes dom

HTML

<form class="form-inline"> 
    <div class="form-group"> 

     <div style="display: inline-flex" class='input-group date' id='datetimepicker1'> 
      <input placeholder="Start Date" id="pick1" type='text' class="form-control"/> 
      <span class="input-group-addon"> 
       <span class="glyphicon glyphicon-calendar"></span> 
      </span> 
     </div> 
    </div> 
    <div class="form-group"> 
     <div style="display: inline-flex" class='input-group date' id='datetimepicker2'> 
      <input placeholder="End Date" id="pick2" type='text' class="form-control"/> 
      <span class="input-group-addon"> 
       <span class="glyphicon glyphicon-calendar"></span> 
      </span> 
     </div> 
    </div> 
    <div class="form-group"> 
     <input class="form-control" type="text" v-model="Keyword" placeholder="keyword"> 

    </div> 

     @*Start Date<input type="text" v-model="StartDate" placeholder="Start Date" style="width: 177px" /> 
     End Date <input type="text" v-model="EndDate" placeholder="End Date" style="width: 177px" />*@ 
     <button type="button" v-show="resetShow" class="btn btn-primary btn-lg " v-on:click="reset" id="reset-btn">Reset filters</button> 
     <button type="button" v-show="GetShow" type="button" class="btn btn-primary btn-lg " v-on:click="getEdges">Get Edges</button> 
     <button v-show="GetShow" type="button" class="btn btn-primary btn-lg " v-on:click="getNodes">Get Nodes</button> 
     <button v-on:click="send" type="button" class="btn btn-default" id="load" >Submit</button> 
    <span v-if="loading" id="loader" style="display:none"> <i style="font-size: 197%; color: purple" class='fa fa-circle-o-notch fa-spin'></i> <span style="font-size: 190%"> Processing </span> </span> 

Javascript

var vm = new Vue({ 
el: '#main', 
data: { 
    resetShow: false, 
    Keyword: '', 
    StartDate: '2016-06-08T17:03:36.000Z', 
    EndDate: '2016-06-16T17:03:36.000Z', 
    Dialog: [], 
    EdgeList: [], 
    NodeList: [], 
    loading: false, 
    StartDate1: '', 
    GetShow: false 
}, 
// define methods under the `methods` object 
methods: { 

    getById: function(event) { 

    }, 

    send: function(event) { 


     this.loading = true; 
     console.log(this.StartDate1); 
     var StartDate = $('#datetimepicker1').data("DateTimePicker").date().utc().format().split('+')[0]+".000Z"; 
     var EndDate = $('#datetimepicker2').data("DateTimePicker").date().utc().format().split('+')[0]+".000Z"; 



     if (this.Keyword != null) { 

      var g = GetElasticSearch(this.Keyword, StartDate, EndDate); 
      s.graph.clear(); 
      s.graph.read(g); 
      sigma.canvas.edges.autoCurve(s); 
      s.refresh(); 
      // Start the ForceLink algorithm: 
      sigma.layouts.startForceLink(); 
      //Louv 
      var louvainInstance = sigma.plugins.louvain(s.graph, 
      { 
       setter: function(communityId) { this.my_community = communityId; } 
      }); 
      var nbLevels = louvainInstance.countLevels(); 
      console.log(nbLevels); 
      var partitions = louvainInstance.getPartitions(); 
      var nbPartitions = louvainInstance.countPartitions(partitions); 
      // Color nodes based on their community 
      s.graph.nodes() 
       .forEach(function(node) { 
        //console.log(node.my_community); 
        node.color = colors[node.my_community]; 
       }); 
      s.refresh({ skipIndexation: true }); 

      s.graph.nodes() 
       .forEach(function(node) { 
        node.color = colors[node.my_community]; 
       }); 
      s.refresh({ skipIndexation: true }); 

      this.loading = true; 
     } 
    } 








} 

});

+0

Пожалуйста, добавьте jsfiddle – gurghet

ответ

1

Vue обновляет DOM асинхронно, когда метод закончен, так сказать.

Таким образом, вы должны сделать часть функции, которая занимает много времени async, поэтому она не блокирует цикл события.

Вы можете использовать setTimeout(callback, 0) для запуска функции async.

Пример: https://jsfiddle.net/Linusborg/tn8q4sub/

(Edit: пример не всегда работает для меня, хотя я не совсем понимаю, почему это - дать ему попробовать с вашей ситуацией)

Для вашего кода, это должно выглядеть примерно так:

send: function(event) { 

    this.loading = true; 

    setTimeout(function() { 
    //rest of the send code. 
    // and at the end: 
    this.loading = false 
    }.bind(this),0) // the `bind(this)` is important! 
} 
+0

работает что-то с тайм-аут 0 не делает функцию запуска асинхр, а останавливает двигатель JS, чтобы позволить рендеринга/живопись догонялки. http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful – nuway

+0

Ум ... нет. Вы четко указываете: «(В действительности, setTimeout() повторно ставит в очередь новый JavaScript в конце очереди выполнения. См. Комментарии для ссылок на более подробное объяснение». - и перечитайте что-то в конце вызова stack * is * асинхронный вызов функции. –

+0

он уверен, что это так. Но я не согласен с тем, что «повторное подавление чего-то в конце стека вызовов является вызовом функции асинхронного вызова», поскольку стек все равно будет выполняться в это последний порядок, и некоторая блокировка может все еще произойти. – nuway

Смежные вопросы