4
votes

I'm following the example here of using a Vue template as a Kendo UI template in their components:

https://www.telerik.com/kendo-vue-ui/components/framework/vue-templates/

The example isn't very clear on how to supply properties to components that are rendered with this method (as opposed to rendering right in the template). I need to supply a single value determined in the parent to all instances of this child component, and I also need to subscribe to emitted events from the child component. My assumption is that there's an overload to Vue.component() that lets me access this functionality?

Edit: Specifically what I am looking for is a way to have a header template for each column created from a Vue component. I need each column's template to receive data from the parent so I know how to construct it, and I also need each column's template to report an event back to the parent.

3
" that are initialized in this matter." ... what does that mean? Also, at a quick glance it seems okay to me, you pass properties to parent element using :prop='value' which you can see in the examplesamayo
Meaning I'm much more familiar with using components in a template like so: <viper-grid :rows="rows" :column-definitions="columnDefinitions" selector-type="radio" @selected="onSelected" />Mike Cole
I'm unfamiliar with using them the way this example illustrates and I'm not sure how to pass in parms or subscribe to emitted events.Mike Cole
@MikeCole, I just thought out one approach if you'd like uses built in props, but probably make the things complicated. we can create one component as template, for that template, only has one div with one specific class like your-template,Sphinx
@MikeCole then in parent component, call let childBuilder = Vue.extend(realComponentOptions); for(item of document.getElementsByClassName('your-template')) { let yourChild = new childBuilder() yourChild.$mount() item.appendChild(yourChild.$el) } to mount your real component (you can save all childs into one data property), then change the props at parent component by yourChild[index].$propsSphinx

3 Answers

1
votes

I think the key point is Step 3 in the link you attached (Kendo Vue Template Usage). (Never touch Kendo Before, if anything wrong, correct me, thanks.)

First, please open this Vue kendo Sandbox, you will find one dropdownlist then each option is one button plus one text. If you click the button, it will call one method in MyTemplate.vue and another Method at DropDownStyle.vue, then its background of each option is blue which passed from DropDownStyle.vue.

Kendo will bind this function of Step 3 to its attribute=template, then fisrt parameter (and only one) is each element of the data-source.

Then this function need to return one object including template and templateArgs, then Kendo construct it.

So my solution is add your function/callback/styles into templateArgs, then do what you need at MyTemplate.vue.

Below is the codes extended from Step 3.

  methods: {
    getMyTemplate: function (e) {
      // parameter=e: it is the value of each element of the dropdown
      e.callback = this.eventCallback
      e.styles="background-color:blue"
      return {
            template: MyTemplate,
            templateArgs: e
        }
    },
    eventCallback: function (data) {
      console.log(this.dropdowns)
    }
  }

Below is MyTemplate.vue.

<template>
    <span :style="templateArgs.styles">
        <button @click="buttonClick();templateArgs.callback()">{{templateArgs.value}}</button>
        {{templateArgs.text}}
    </span>
</template>

<script>
export default {
    name: 'template1',
    methods: {
        buttonClick: function (e) {
            console.log('props',this.templateArgs.styles)
        }
    },
    data () {
      return {
          templateArgs: {
            callback:function(){
              console.log('Test')
            },
            styles:''
          }
      }
    }
}
</script>
1
votes

Very odd design choice in terms of passing the template in like they do. Avoiding the KendoUI and focusing on VueJS methods - could you use provide/inject? Providing the value in the parent and injecting in any of the children?

Also a plugin could be created to keep track of events or values you want available to all components in the application. In essence the plugin would be a service. A singleton object that is only instantiated once.

0
votes

The documentation is indeed lacking. I agree with you on that. I took a different approach with templating for Kendo UI component and got this working: https://codesandbox.io/s/github/ariellephan/vue-kendoui-template

To start, I have this dropdown component that utilizes Kendo dropdown list component:

<template>
  <div>
    <p>Style with template {{template}}</p>
    <kendo-dropdownlist 
                    :template="template"
                    :headerTemplate="headerTemplate"
                    :data-source="dataSourceArray"
                    :data-text-field="'text'"
                    :data-value-field="'value'"
                    :filter="'contains'">
    </kendo-dropdownlist>
  </div>
</template>

<script>
export default {
  name: "Dropdown",
  props: ["dataSourceArray", "template", "headerTemplate"],
  data() {
    return {
      value: "Click Me",
      text: "I'm in Template template"
    };
  }
};
</script>

To render different styles/templates, I parsed in props from the parent component. In this case, DropdownStyles

<template>
  <div id="DropdownStyles">
    <h1>KendoUI dropdown instances with different templates</h1>
    <Dropdown
  v-for="dropdown in dropdowns"
  v-bind:key="dropdown.id"
  v-bind:title="dropdown.title"
  v-bind:data-source-array="dropdown.dataSourceArray"
  v-bind:template="dropdown.template"
  v-bind:headerTemplate="dropdown.headerTemplate"
></Dropdown>
  </div>
</template>

<script>
import Dropdown from "./Dropdown";
import DropdownTemplate from "./DropdownTemplate";

export default {
  name: "DropdownStyles",
  components: { Dropdown },
  data() {
    return {
      dropdowns: [
        {
          id: 1,
          title: "x style",
          dataSourceArray: [
            "Football",
            "Tennis",
            "Basketball",
            "Baseball",
            "Cricket",
            "Field Hockey",
            "Volleyball"
          ],
          template: `<strong class="custom-dropdown">x #:data#</strong>`,
          headerTemplate: DropdownTemplate.template
        },
        {
          id: 2,
          title: "+ style",
          dataSourceArray: [
            "Football",
            "Tennis",
            "Basketball",
            "Baseball",
            "Cricket",
            "Field Hockey",
            "Volleyball"
          ],
          template: `<strong class="custom-dropdown">+ #:data#</strong>`,
          headerTemplate: `<div><h3 style="padding-left:10px;">Sports 2</h3></div>`
        }
      ]
    };
  }
};
</script>

You can move the template into its own file or function. For example, the first drop down is using DropdownTemplate for its headerTemplate:

DropdownTemplate.vue

<script>
export default {
  name: "DropdownTemplate",
  props: ["header"],
  template: `<div>
    <div><h3>Sports 1</h3></div>
  </div>`,
  data() {
    return {};
  }
};
</script>
<style scoped>
h3 {
  padding-left: 10px;
}
</style>