2016-10-26 10 views
3

移行する前にajaxが完了した場合、少なくとも2秒間スピナーを表示する必要があります。Ajaxがtransition.next()より前にVue.jsで完了したら、少なくとも2秒待ってください

route: { 
    data(transition) { 

     this.getDelayedData(); 
     transition.next(); 
     } 
    }, 

methods:{ 
    getSliders(){ 
      this.$http.get('/api/sliders/getsliders') 
        .then(sliders =>{this.sliders = sliders.data 

       }); 
     }, 
    getPosts(){ 
      this.$http.get('/api/posts/getposts') 
        .then(posts =>{this.posts = posts.data.data 

        }); 
     }, 
    getDelayedData(){ 
     function timer() { 
      var dfd = $.Deferred(); 
      setTimeout(function() 
        { 
        console.log("done"); 
        }, 2000,dfd.resolve); 
        return dfd.promise(); 
        } 
      $.when(this.getPosts(), this.getSliders(),timer()) 
       .done(); 
     } 
    } 

作業

私は、次のしている

けどありえないが、私はthisポスト を読み込むコードを実装しようとしましたが、$ .when関数はsetTimeout関数の実行が終了するまで待ってイマイチ。

+0

あなたの 'function timer(){...}'は、内部に新しいスコープを作成しています。だから、技術的に 'this.getPosts()'と 'this.getSliders()'は 'timer'関数の中で動作すべきではありません。どこでも習慣として[arrow functions](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions)を使う必要があるかもしれません。 – Mani

答えて

4

あなたはすでに私の他の答えを受け入れてきたが、私は、以下に説明するようにコードは、大幅に向上させることができると思う:

両方がDOMを変更すると一般的に、Vue.jsjQueryを混在しないことをお勧めします:

  • Vue.jsは、そのモデルのビューのバインディングのために、その反応性システム

  • を使用してDOMに非常に強いホールドを持っています
  • jQueryは、一部のクイックフィックスソリューションで使用する場合は、classまたはidセレクタを使用して変更できます。

フロントエンドの問題をデバッグするのに多くの時間を費やしてしまいます。これは、ビジネス要件から離れたところです。また、Vue.jsには最新のブラウザが既に必要なため、技術的にはjQueryはブラウザの互換性のためにあまり効果がありません。

あなたが背後jQueryを出るまで開いているのであれば、ここでもう一つの方法は次のとおりです。

getDelayedData() { 
    // Create a new Promise and resolve after 2 seconds 
    var myTimerPromise = new Promise((resolve, reject) => { 
     setTimeout(() => { 
      // callback function for timer, gets called after the time-delay 
      // Your timer is done now. Print a line for debugging and resolve myTimerPromise 
      console.log("2 seconds up, resolving myTimerPromise") 
      resolve(); 
     }, 2000); // This promise will be resolved in 2000 milli-seconds 
    }); 

    // Start displaying ajax spinner before fetching data 
    this.displaySpinner = true; 

    // Fetch data now, within Promise.all() 
    Promise.all([myTimerPromise, this.getPosts(), this.getSliders()]).then(() => { 
     // Hide the spinner now. AJAX requests are complete, and it has taken at least 2 seconds. 
     this.displaySpinner = false; 
     console.log("Data fetched for sliders and posts"); 
    }); 
} 

上記のコードはまたあなたのAjaxスピナーを活性化したり無効にしている、this.displaySpinnerを持っている必要があります。あるいは、他のやり方をしているかもしれません。

さらに、getPostsgetSlidersの方法からはreturn this.$http.get(..)が必要です。

注:上記のコードはテストしていません。必要に応じてデバッグする必要があります。

getDelayedData() { 
    // Create a new Promise and resolve after 2 seconds 
    var myTimerPromise = new Promise((resolve, reject) => { 
     setTimeout(resolve, 2000); // "resolve" is already a function, no need for another anonymous function here 
    }); 
    // and do the other stuff here... 
} 

が、私はこの方法を好むだろう:それは作業を開始したら、次のようにhttps://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

、あなたがmyTimerPromiseを簡素化することができます:それは、このリファレンスドキュメントで与えられるPromise.all()の私の理解に基づいて、動作するはずですそれはjQueryを避けるためです。それで私のVue.jsアプリは、gzipされた30 KBの小さなものになることがあります。逆にjQueryをバンドルすると、100 KBを超えることができます。

+0

驚くべき答え@マニ、あなたは私に非常に多くのことを教えてくれました。もちろん、私はjqueryを残します。データルートフックに達すると、$ loadingRouteData varを使ってSpinner Imを教えてください。私はちょうどあなたのコードを研究し、変更を加える必要があります。それがどういったものだったのか教えてくれるでしょう。もう一度ありがとう! – FerchoCarcho

+0

@FerchoCarchoあなたのご意見ありがとうございます。また、これを選択した回答に感謝します。私はこれが私の他の答えよりもコミュニティを助けるだろうと思う。 – Mani

+0

遅れて申し訳ありません。タイムゾーン:D。あなたは再び真実です、私は一箇所で物事を設定するのは難しいですが、あなたのガイドは非常に便利です。 – FerchoCarcho

1

あなたのメソッド(getSliders()およびgetPosts())が約束を返さないため、問題が発生したと考えられます。したがって、あなたのdeferredタイマーは、これらのgetメソッドで何が起こっているかを知る方法がありません。

this.$http.get(..)Vue-resourceは約束を返します。 http://www.erichynds.com/blog/using-deferreds-in-jquery、あなたは質問に言及他のstackoverflowの答えにリンクされている。ここに挙げた例を、以下の

getSliders(){ 
    // Fetch sliders and "return" the promise object 
    return this.$http.get('/api/sliders/getsliders') 
     .then(sliders =>{ 
      // The data on vue is already being set here. So it will not wait for timeout. 
      this.sliders = sliders.data 
      // Instead you may try to set it on "this.sliders_temp" and then change later to "this.sliders" 
     }); 
}, // and so on... 

を次のようにあなたはそれを返すことができます。彼らはその機能に$.get(..)を返します。

return this.$http.get(...)でも、$httpの成功ハンドラ内にthis.slidersが既に設定されているため、上のコードサンプルに示されているように、return this.$http.get(...)でもまだ機能しません。そのため、VueテンプレートはすぐにUIを更新します。あなたはあなたのアプリにとってより良い戦略を考える必要があります。

+0

データがページ上で更新されるのを気にせず、スピナーを2秒間だけしたいのであれば、単に 'return this。$ http.get(..)'が動作します。 – Mani

+0

ありがとう@助けのためのマニ:D – FerchoCarcho

+0

私はそれが大幅に改善することができると信じています。私の他の答えをチェックしてください.-) – Mani

関連する問題