question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Compile dynamic template and bind vue event listeners

See original GitHub issue

I have a datatable component and i am using it on many different components/pages with different data. i just pass an object with the columns and it renders it. and some datatables have action buttons (edit, delete), some don’t. and each of the action button should trigger a function on the component it was called on.

Here’s the code. https://jsfiddle.net/hwk7bLhf/4/

var datatableComponent = {
  template: '#datatable-template',

  props: {
    columns: { default: function(){ return [] }, type: Array },
    url: {default: null, type: String },
  },

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

  mounted: function() {
    this.getData();
  },

  methods: {
    getData: function() {
      // fetch data from api using defined url
      this.data = {
        items: [
          { id: 1, title: 'Test 1' },
          { id: 2, title: 'Test 2' },
          { id: 3, title: 'Test 3' },
        ]
      }
    }
  }
}

Vue.component('datatable', datatableComponent);

new Vue({
    el: '#app',
  data: function() {
    return {
      columns: [
        { key: 'id', title: 'ID' },
        { key: 'title', title: 'Title' },
        { key: 'id', title: 'Options', html: function(item) {
            return '<button @click="editItem('+item.id+')">Edit</button>';
        }}
      ]
    }
  },

  methods: {
    editItem: function(item) {
        alert('editing item')
    }
  }
})
<div id="app">
  <datatable :columns="columns"></datatable>
</div>

<script type="text/x-template" id="datatable-template">
    <div>
  Datatable title
        <table>
            <thead>
                <tr>
                    <th v-for="column in columns" v-text="column.title"></th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="item in data.items">
                    <td v-for="column in columns">
            <div v-if="typeof column.html != 'undefined'" v-html="column.html(item)"></div>
            <div v-else v-text="item[column.key]"></div>
          </td>
                </tr>
            </tbody>
        </table>
    </div>
</script>

It would be cool to be if i was able to somehow compile the ‘html’ content given in the columns object and use the vue provided elements and directives/plugins/mixins, etc…

I tried turning the column definition into components but i am not sure if it’s a good idea to define global components for every column that has a html field with vue logic in it.

In vue 1 I used partials that handled this problem very well, but now with vue2 it’s gotten a little harder 😛

Do any of you guys have idea or can think of a way to solve this problem?

There are also other people wondering if it’s possible: http://forum.vuejs.org/t/on-vue2-0-i-should-be-how-to-dynamic-compile-the-template-and-binding-template-events/117 http://forum.vuejs.org/t/vue-js-1-x-this-compile-equivalen-vue-js-2-x-please/515 http://forum.vuejs.org/t/vue-2-0-dynamic-event-handling/916/2

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

14reactions
yyx990803commented, Oct 6, 2016

This should be addressed in 2.1 via “template slots” - basically, a slot element that serves as a template that will be given data from the child component. Similar to passing a render function down instead of passing down already-rendered elements.

I’ll open an issue discussing this feature in details when we start working on it.

4reactions
chrislandezacommented, Jan 4, 2017

Any updates to this issue? @envomer - Have you solved this problem? I’m also trying to implement Datatables on vue 2.

In Vue 1.x all I had to do is recompile the Datatable DOM inside the Datatable’s drawCallback() function to make my action buttons work:

...
$('#datatable').dataTable({
   ...
    drawCallback: function (settings) {
        var $element = $('#app-datatable');
        vm.$compile($element.get(0));
    },
 ...
});

But it does not work any more because the “$compile” has been removed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

vue.js - Programmatically bind custom events for dynamic ...
With Vue 2.2+, you can programmatically add an event listener with $on(eventName, callback) : new Vue({ el: '#app', created() { const EVENTS ...
Read more >
Event Handling - Vue.js
The template compiler detects method handlers by checking whether the v-on value string is a valid JavaScript identifier or property access path.
Read more >
[Solved]-Vue - Dynamic component event listener-Vue.js
The best way is to have the method/handler inside the parent component and then trigger is using the emit functionality such that in....
Read more >
Handling Events with Vue.js
When you build a dynamic website with Vue you'll most likely want it ... If we bind a method to our event handling...
Read more >
An introduction to dynamic list rendering in Vue.js
We're binding the properties of the tweet object prop on to the component template with the help of the Mustache syntax: {{ }}...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found