2017-06-05 15 views
1

私はvue jsが新しく、より多くのデータを表示するためにブートストラップモーダルで使用しようとしています。私のシナリオは、複数のレコードを持つテーブルと、ブートストラップモーダルでクリックされたレコードの深さの詳細を表示するボタンです。最初のボタンをクリックすると、キャッシュされ、異なる詳細の別のボタンを選択している間は更新されません。ブーストモードがvue js v2と双方向バインディングで更新されない

誰かが間違っているのを見ていますか?

(それはLaravel、jQueryとVueJSの組み合わせです)

HTML表:

<table class="table table-striped"> 
<thead> 
    <tr> 
     <th>E-mail address</th> 
     <th>Status</th> 
     <th>Sent at</th> 
     <th>Expires in</th> 
     <th></th> 
    </tr> 
</thead> 
<tbody> 
    <tr> 
     <td class="v-align-middle"> 
      [email protected] 
     </td> 
     <td class="v-align-middle"> 
      <span class="label label-default"> 
       pending 
      </span> 
     </td> 
     <td class="v-align-middle"> 
      2017-06-05 17:59:15 
     </td> 
     <td class="v-align-middle"> 
      29 days 
     </td> 
     <td> 
      <div class="btn-group pull-right"> 
       <a href="#" class="btn btn-default" data-toggle="modal" data-target="#inviteDetailsModal" data-email="[email protected]"> 
        <i class="fa fa-eye"></i> 
       </a> 
      </div> 
     </td> 
    </tr> 
    <tr> 
     <td class="v-align-middle"> 
      [email protected] 
     </td> 
     <td class="v-align-middle"> 
      <span class="label label-default"> 
       pending 
      </span> 
     </td> 
     <td class="v-align-middle"> 
      2017-06-05 13:27:25 
     </td> 
     <td class="v-align-middle"> 
      29 days 
     </td> 
     <td> 
      <div class="btn-group pull-right"> 
       <a href="#" class="btn btn-default" data-toggle="modal" data-target="#inviteDetailsModal" data-email="[email protected]"> 
        <i class="fa fa-eye"></i> 
       </a> 
      </div> 
     </td> 
    </tr> 
</tbody> 

はJavaScript:

$('[data-target="#inviteDetailsModal"]').on('click', function() { 
    let email = $(this).data('email'), 
     baseUrl = $('html').data('base'); 

    Vue.component('invite-details', { 
     data: function() { 
      return { 
       email: null, 
       token: null, 
       logs: [], 
       expires: null 
      } 
     }, 
     methods: { 
      update: function (data) { 
       this.email = data['email']; 
       this.token = data['token']; 
       this.logs = data['logs']; 
       this.expires = data['expires']; 
      }, 
      fetchData: function() { 
       this.$http.get(baseUrl + '/system/invites/' + email + '/details') 
        .then(response => { 
         this.update(response.body); 
        }, response => { 
         console.log('whoops something went wrong'); 
        }); 
      } 
     }, 
     mounted: function() { 
      this.$el.addEventListener('shown.bs.modal', this.fetchData()); 
     }, 
     beforeDestroy: function() { 
      this.$el.removeEventListener('shown.bs.modal', this.fetchData()); 
     } 
    }); 

    new Vue({ 
     el: '#inviteDetailsModal' 
    }); 
}); 

ブートストラップモーダル:

<div class="modal fade slide-up" id="inviteDetailsModal" tabindex="-1" role="dialog" aria-hidden="true"> 
<div class="modal-dialog"> 
    <div class="modal-content-wrapper"> 
     <invite-details inline-template> 
      <div class="modal-content" id="details"> 
       <div class="modal-header clearfix text-left"> 
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true"> 
         <i class="pg-close fs-14"></i> 
        </button> 
        <h5> 
         Invite details for <span class="semi-bold">@{{ email }}</span> 
        </h5> 
        <p class="p-b-10"> 
         <span data-tooltip="true" data-placement="bottom" title="token"> 
          <em>@{{ token }}</em> 
         </span> 
        </p> 
       </div> 
       <div class="modal-body"> 
        <table class="table table-striped"> 
         <thead> 
         <tr> 
          <th>#</th> 
          <th>Sent at</th> 
          <th>Status</th> 
         </tr> 
         </thead> 
         <tbody> 
         <tr v-for="log in logs"> 
          <td>@{{ log.number }}</td> 
          <td>@{{ log.sentAt }}</td> 
          <td>@{{ log.status }}</td> 
         </tr> 
         </tbody> 
        </table> 
       </div> 
       <div class="modal-footer text-center"> 
        <span class="hint-text"> 
         <em>expires in <strong>@{{ expires }}</strong> days</em> 
        </span> 
       </div> 
      </div> 
     </invite-details> 
    </div> 
</div> 

+0

私はあなたが1つのモーダルコンポーネントを使用していて、クリックされたテーブルの特定のボタンに基づいてコンテンツを変更しようとしていますか?その場合、 'mounted'フックは、コンポーネントが最初にマウントされたときに1回だけ起動します。 – thanksd

+0

これは正しいので、テーブル内でクリックされた特定のボタンに基づいてモーダルコンテンツを更新するにはどうすればよいですか?何か提案はありますか? – jaimyborgman

答えて

1

さてさて、私はこの作業を取得するために深くに掘らとあなたがVueJSで新しいだった言及したので、余分なマイルを行ってきました。あなたは完全なコードを削除する前に、jQueryの考え方とVueJS ;-)

まず、いくつかの簡単なメモに行くところ私はあなたのコードでは、私の昔の自分を認識:

  • を参照に、テーブルDBの行の整数IDを使用しますユーザーはどこにでもいます。 この方法でメールが更新された場合でも、フロントエンドのユーザーは です。コードを調べることによって、私はそれが更新data財産だからメールが( を変えることができることを見たが、また、 あなたGETリクエストで使われています:その後baseUrl + '/system/invites/' + email + '/details'

  • は、あなたが簡単に を独自のインスタンスを生成するには、このIDを使用することができますあなたのモーダル:-)これはあなたがVueJSで作業したい方法です!

  • 複数の場所で同じデータを使用しているので、店舗の場合は Vuexをご覧ください。最初は気にならないように見えるかもしれませんが、一度 あなたはそれを把握すると素晴らしいです。あなたの場合、元のテーブルのモーダルで同じデータセットが になります。更新すると、 すべてが更新されます!

  • Vuexを使用すると、どこからでもアップデートを開始できます。現在、目のボタンをクリックするたびにデータ が更新されます。しかし、これは です。私はモーダルのテンプレートのボタン部分を とし、クリックするたびにfetchData()( のコンソールを確認してください)を呼び出します。あなたが理想的にしたいことは、Vuexを使用して、 のすべてを単一点の真理データセットから生成することです。現在、 モーダルのデータが更新された場合、元のテーブルは更新されません。

  • VueJSでは、独自のモーダルを作成するのと同じように簡単です。 の上限は、v-ifを使用できるため、コード内のオーバーヘッドが少なくなるため、実際に必要でない限り はDOMにロードされません。現在のコードから と判断すると、詳細ボタンがクリックされることがありました。

  • お持ちでない場合はVueJSデバッガをインストールします。 https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd、 をそれはあなたがボンネットの下に「見る」のに役立ちます。

今すぐコードを入力してください。右var app = new Vue({線の上

import JaimyTable from './components/stackoverflow/JaimyTable.vue' 

:まず、あなたのapp.jsファイルに次の行を追加します。そして、あなたはこのようなものになってしまうので、あなたのコンポーネントに追加します。

<template> 
    <div class="container"> 
     <table class="table table-striped"> 
      <thead> 
      <tr> 
       <th>E-mail address</th> 
       <th>Status</th> 
       <th>Sent at</th> 
       <th>Expires in</th> 
       <th></th> 
      </tr> 
      </thead> 
      <tbody> 
      <tr> 
       <td class="v-align-middle"> 
        [email protected] 
       </td> 
       <td class="v-align-middle"> 
      <span class="label label-default"> 
       pending 
      </span> 
       </td> 
       <td class="v-align-middle"> 
        2017-06-05 17:59:15 
       </td> 
       <td class="v-align-middle"> 
        29 days 
       </td> 
       <td> 
        <div class="btn-group pull-right"> 

         <jaimy-modal id="1"></jaimy-modal> 

        </div> 
       </td> 
      </tr> 
      <tr> 
       <td class="v-align-middle"> 
        [email protected] 
       </td> 
       <td class="v-align-middle"> 
       <span class="label label-default"> 
        pending 
       </span> 
       </td> 
       <td class="v-align-middle"> 
        2017-06-05 13:27:25 
       </td> 
       <td class="v-align-middle"> 
        29 days 
       </td> 
       <td> 
        <div class="btn-group pull-right"> 

         <jaimy-modal id="2"></jaimy-modal> 

        </div> 
       </td> 
      </tr> 
      </tbody> 
     </table> 
    </div> 
</template> 

<script> 
    import JaimyModal from './JaimyModal.vue' 

    export default { 

     components: { JaimyModal }, 

     props: [], 

     mixins: [], 

     data: function() { 
      return { 
       // 
      } 
     }, 

     computed: { 
      computed_variable() { 
       return ''; 
      } 
     }, 

     created() { 
      // 
     }, 

     mounted() { 
      // 
     }, 

     methods: { 
      // 
     }, 

     watch: { 
      // 
     } 
    } 
</script> 

<jaimy-modal id="1"></jaimy-modal>ラインに注意してください。

import JaimyTable from './components/stackoverflow/JaimyTable.vue' 

var app = new Vue({ 

    components: { 
     JaimyTable, 
    }, 

}); 

をここでJaimyTable.vueファイルです。 v-forを使用して、すべての<tr>行を自動的に生成することができます。id=がデータベースのIDに対応することを確認してください。すべての魔法が起こるJaimyModal.vueのための今

<template> 
    <div> 
     <a href="#" class="btn btn-default" data-toggle="modal" :data-target="'#inviteDetailsModal' + id" @click="fetchData()"> 
      <i class="fa fa-eye"></i> 
     </a> 

     <div class="modal fade slide-up" :id="'inviteDetailsModal' + id" tabindex="-1" role="dialog"> 
      <div class="modal-dialog"> 
       <div class="modal-content-wrapper"> 


        <div class="modal-content" id="details"> 
         <div class="modal-header clearfix text-left"> 
          <button type="button" class="close" data-dismiss="modal" aria-hidden="true"> 
           <i class="pg-close fs-14"></i> 
          </button> 
          <h5> 
           Invite details for <span class="semi-bold">{{ email }}</span> 
          </h5> 
          <p class="p-b-10"> 
         <span data-tooltip="true" data-placement="bottom" title="token"> 
          <em>{{ token }}</em> 
         </span> 
          </p> 
         </div> 
         <div class="modal-body"> 
          <table class="table table-striped"> 
           <thead> 
           <tr> 
            <th>#</th> 
            <th>Sent at</th> 
            <th>Status</th> 
           </tr> 
           </thead> 
           <tbody> 
           <tr v-for="log in logs"> 
            <td>{{ log.number }}</td> 
            <td>{{ log.sentAt }}</td> 
            <td>{{ log.status }}</td> 
           </tr> 
           </tbody> 
          </table> 
         </div> 
         <div class="modal-footer text-center"> 
          <span class="hint-text"> 
           <em>expires in <strong>{{ expires }}</strong> days</em> 
          </span> 
         </div> 
        </div> 


       </div> 
      </div> 
     </div> 
    </div> 
</template> 

<script> 
    export default { 

     props: ['id'], 

     data: function() { 
      return { 
       email: null, 
       token: null, 
       logs: [], 
       expires: null, 
       baseUrl: 'https://yourbaseurl.com', 
      } 
     }, 

     mounted: function() { 
      // 
     }, 

     methods: { 
      update: function (data) { 
       this.email = data['email']; 
       this.token = data['token']; 
       this.logs = data['logs']; 
       this.expires = data['expires']; 
      }, 
      fetchData: function() { 
       console.log('data fetched'); 

       // Commented out for local purposes 
//    this.$http.get(this.baseUrl + '/system/invites/' + this.email + '/details') 
//      .then(response => { 
//       this.update(response.body); 
//      }, response => { 
//       console.log('whoops something went wrong'); 
//      }); 

       // Dummy data 
       this.update({ 
        email: '[email protected] ' + this.id + '.com', 
        token: 'token123123asdsasdasdasd', 
        logs: [ 
         { 
          number: 1, 
          sentAt: '2017-01-01', 
          status: 'Ok', 
         }, 
         { 
          number: 2, 
          sentAt: '2017-02-01', 
          status: 'Failed', 
         }, 
        ], 
        expires: '2017-10-01' 
       }); 
      } 
     }, 

    } 
</script> 

重要ここで注意することは、数は小道具のIDに対応するボタン、中:data-target="'#inviteDetailsModal' + id"一部です。 :を使用すると、式が作成され、固有の参照に解決されます。

ご覧のとおり、セットアップはこれまでとはまったく異なります。ここで、モーダルは、テーブル行のネストされたコンポーネントです。コンポーネントを外観と機能の繰り返し部分として考えてみると、その中にユニークなデータが含まれていれば、状況はとなり、が高速になります。それをLaravelのモデルと考えてください。

デザイン(CSS)、マークアップ(HTML)、機能(JS)を分けなければならないと言われてから、1つのファイルにすべてが座っているのは変です。しかし、それを受け入れ、あなたはVueJSと恋に落ちるでしょう:D

そしてVuexを見てください!次に、同じデータセットを使用して操作する複数のコンポーネントが得られます。これは神です!

最後に、あなたはfn.triggerなどのものを使うことを考え始めます。あなたはVueJSに間違っています。それを心に留めてください:)それはあなたがページで作業するのに必要なすべてのツールを持っていますし、いくつか!

ハッピーコーディング!

+0

jQueryのような "古い"方法であなたの心が鍛えられている間に、あまりにも深い説明@ stan-smuldersのおかげで、それは本当にありがとう、それは私をたくさん助けてくれました!魅力的な作品! – jaimyborgman

+0

あなたはJaimyを歓迎する以上のものです!物事がクリックされるとその素晴らしいフレームワークはそれを維持し、あなたはすぐにそれについての素晴らしい実践的な知識を持っています:) –

0

使用すると、1つのモーダル・コンポーネントを使用していて、テーブル内の特定のボタンに基づいてその内容を変更しようとしているのではmountedフックが唯一の構成要素が最初に装着した場合、一度起動するように起こっている、クリックされました。

あなたが望むのは、モーダルが表示されるたびにコンテンツが更新されることです。

最初に、あなたのコンポーネントは1つだけemail小道具が必要なようです。彼らはコンポーネントに渡されていない(私は仮定している)ことから、コンポーネントのdata方法にあるように小道具の残りの部分を移動:

props: ['email'], 
data: function() { 
    return { 
    token: null, 
    logs: null, 
    expires: null, 
    } 
} 

その後、私はと呼ばれる新しいメソッドを作成しますfetchData$http.getコールを置くために:あなたのモーダルコンポーネントのmountedフックで

fetchData: function() { 
    this.$http.get('http://localhost:2000/system/invites/' + this.email + '/details') 
    .then(response => { 
     this.update(response.body); 
    }, response => { 
     console.log('whoops something went wrong'); 
    }); 
} 

、jQueryのを使用して、ブートストラップモーダルのshowイベントにリスナーを追加します。そして、コンポーネントのbeforeDestroyフックでリスナーを削除してください:

mounted() { 
    $(this.$el).on('shown.bs.modal', this.fetchData); 
}, 
beforeDestroy() { 
    $(this.$el).off('shown.bs.modal', this.fetchData); 
} 

、モーダルのshowイベントが発生するたびに、$http.getリクエストは、コンポーネントのemailプロパティの現在の値に基づいて発生します。

Here's an example fiddle.

+0

説明をありがとうが、まだモーダルが内容を更新しないという問題があります...私は今、持っている完全なコードで私の最初のメッセージを更新しました – jaimyborgman

+0

@jaimyborgman明らかに、jQueryが必要ですブートストラップのイベントをリスンします。私は私の答えを更新しました – thanksd

+0

mmmまだ更新していません...私はそこにconsole.log()を設定するとbeforeDestroyフックが呼び出されないようです... – jaimyborgman

関連する問題