Dynamic Columns in DataGrid with Template (in separate file) - VUE 3

Hi,

I would like some help regarding Template and Dynamic Columns. So let's say first, dynamic columns are working fine (vue3, and ej2-vue-grid latest versions loaded before this article) until "you try to implement template" which is not defined in the same file (as in your example)

https://ej2.syncfusion.com/staging/vue/documentation/getting-started/vue3-tutorial/?_ga=2.170605475.2071104109.1629472111-1554240977.1627230331#template-usage

Your grid also put in separate component, which accepts prop columns, but let's simplify it.

So, what do I have:

columns: [
        { type: "checkbox"width: "50"},
        { field: "id"visible: falseisPrimaryKey: true },
        { field: "name"headerText: "Name"textAlign: "Right"width: "100"template: this.linkTemplate }
]


above, there is:

import linkColumnTemplate from 'shared/Grid/LinkColumn';

const app = createApp();
var linkColumn = app.component('linkTemplate'linkColumnTemplate);


and in methods

methods: {
    linkTemplate: function () {
          return { template: linkColumn };
    }
}


So when I debug your code, which takes some time but :)

  • @syncfusion/ej2-grids/src/grid/modules/column.js, line 180 it enters templateCompiler (only if template is defined as  method, not as data function as in your example). The component is in VUE2 format, not written in composition API.
  •  @syncfusion/ej2-vue-base/src/template.js, compile function (which we enter properly) , line 38
  • templateCompRef = object.template._context.components[templateElement.name];

    So we do have here, list of components in object.template._context.components as {{linkTemplate: {...}}} => this is all fine, but

    templateElement.name is not set to "linkTemplate" but to string "bound linkTemplate" - which obviously returns nothing and everything "dies".

    The grid (does not display an error in rendering), there is no errors in console - nothing. Grid says "No records to display" - which is not true. And it also say "1 of 1 pages (2 items)" which is in contradiction with last statement.


    Any help would be nice?

    BR,

    Vedran


    





3 Replies

VH Vedran Hudec August 21, 2021 08:46 PM UTC

Replying to myself if anyone get in this situation, but I'm still thinking this is a bug :)


If we put definition of "linkTemplate" to data as function:

linkTemplate: function () {
          return { template: linkColumnname: "linkColumn" };
      },


and we put columns definition in computed property (which is misuse of vue computed props)

columns() {
       return [
        { type: "checkbox"width: "50"},
        { field: "id"visible: falseisPrimaryKey: true },
        { field: "name"headerText: "Name"textAlign: "Right"width: "100"template: this.linkTemplate },


Then your component is working by your design.



RS Rajapandiyan Settu Syncfusion Team August 24, 2021 03:15 AM UTC

Hi Vedran, 
 
Thanks for contacting Syncfusion support. 
 
Based on your requirement, you want to bind the columnTemplate which created from another component file. Currently, we are preparing the sample with this and will update the further details on or before Aug 26th 2021. 
 
We appreciate your patience until then. 
 
Regards, 
Rajapandiyan S 



RS Rajapandiyan Settu Syncfusion Team August 26, 2021 02:06 PM UTC

Hi Vedran,  

Thanks for your patience. 

Based on your requirement, you want to render the ColumnTemplate in the Grid which is referred from another module. We have prepared a sample for your requirement. You can get it from the below link, 



[ColumnTemp.vue] 

<template> 
  <div id="dialogTemplate1"> {{data.OrderID}} - {{data.CustomerID}} 
  </div> 
</template> 
<script> 
export default { 
  name: "dialogTemplate1", 
  data() { 
    return { 
    }; 
  }, 
}; 
</script> 


[App.vue] 

<template> 
  <div id="app"> 
    <ejs-grid :dataSource='data' :allowPaging="true" :actionFailure="actionFailure"> 
      <e-columns> 
          <e-column field='CustomerID' width='125' textAlign='Right'></e-column> 
          <e-column field='OrderID' width='125' textAlign='Right'></e-column> 
          <e-column field='ShipCountry' width='125' textAlign='Right'></e-column> 
          <e-column headerText='Employee Image' width='150' textAlign='Center' :template="colTemplate"></e-column> 
      </e-columns> 
  </ejs-grid> 
    </div> 
</template> 

<script> 
import { GridComponent, ColumnsDirective, ColumnDirective, Page } from '@syncfusion/ej2-vue-grids'; 
import dialogTemplate1 from "./ColumnTemp.vue"; 

import { createApp } from "vue"; 
const app = createApp(); 
// Template declaration 
var colVue = app.component("colTemplate", dialogTemplate1); 


export default { 
  name: 'App', 
  components: { 
    'ejs-grid' : GridComponent, 
'e-columns' : ColumnsDirective, 
'e-column' : ColumnDirective, 
  }, 
  data() { 
return { 
  data:  [ 
    { 
       "OrderID":10248, 
       "CustomerID":"VINET", 
       "ShipCountry":"France" 
    }, 
    { 
       "OrderID":10249, 
       "CustomerID":"TOMSP", 
       "ShipCountry":"Germany" 
    }], 
    colTemplate: function () { 
        return { template: colVue}; 
     }, 
}; 
  }, 
  // module injection 
  provide: { 
grid: [Page], 
  } 
}; 
</script> 


please get back to us if you need further assistance with this. 

Regards,  
Rajapandiyan S 


Loader.
Up arrow icon