{"action":"created","issue":{"url":"https://api.github.com/repos/ratiw/vuetable-2/issues/59","repository_url":"https://api.github.com/repos/ratiw/vuetable-2","labels_url":"https://api.github.com/repos/ratiw/vuetable-2/issues/59/labels{/name}","comments_url":"https://api.github.com/repos/ratiw/vuetable-2/issues/59/comments","events_url":"https://api.github.com/repos/ratiw/vuetable-2/issues/59/events","html_url":"https://github.com/ratiw/vuetable-2/issues/59","id":208960889,"number":59,"title":"Recursively find parent for callbacks","user":{"login":"stevendesu","id":1384974,"avatar_url":"https://avatars2.githubusercontent.com/u/1384974?v=3","gravatar_id":"","url":"https://api.github.com/users/stevendesu","html_url":"https://github.com/stevendesu","followers_url":"https://api.github.com/users/stevendesu/followers","following_url":"https://api.github.com/users/stevendesu/following{/other_user}","gists_url":"https://api.github.com/users/stevendesu/gists{/gist_id}","starred_url":"https://api.github.com/users/stevendesu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevendesu/subscriptions","organizations_url":"https://api.github.com/users/stevendesu/orgs","repos_url":"https://api.github.com/users/stevendesu/repos","events_url":"https://api.github.com/users/stevendesu/events{/privacy}","received_events_url":"https://api.github.com/users/stevendesu/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2017-02-20T19:07:18Z","updated_at":"2017-03-04T18:13:06Z","closed_at":null,"body":"I have a fairly simple component set up like so:\r\n\r\n```html\r\n<template>\r\n    <row>\r\n        <column>\r\n            <vuetable url=\"...\"></vuetable>\r\n        </column>\r\n    </row>\r\n</template>\r\n\r\n<script>\r\n    export default {\r\n        data () => {\r\n            return {\r\n                fields: [{name: \"test\", callback: \"test\"}]\r\n            };\r\n        },\r\n        methods: {\r\n            test: (value) => value.split('').reverse().join('')\r\n        }\r\n    }\r\n</script>\r\n```\r\n\r\nWhen trying to call the callback, the following code is triggered in VueTable:\r\n\r\n```js\r\n    callCallback: function(field, item) {\r\n      if ( ! this.hasCallback(field)) return\r\n\r\n      if(typeof(field.callback) == 'function') {\r\n       return field.callback(this.getObjectValue(item, field.name))\r\n      }\r\n\r\n      let args = field.callback.split('|')\r\n      let func = args.shift()\r\n\r\n      if (typeof this.$parent[func] === 'function') {\r\n        let value = this.getObjectValue(item, field.name)\r\n\r\n        return (args.length > 0)\r\n          ? this.$parent[func].apply(this.$parent, [value].concat(args))\r\n          : this.$parent[func].call(this.$parent, value)\r\n      }\r\n\r\n      return null\r\n    },\r\n```\r\n\r\nThe relevant line here is `if(typeof this.$parent[func] === 'function')`... Because `this.$parent` refers to _**the column**_, not my custom component. And of course `<column>` doesn't have a method called `test`\r\n\r\nThis is easily resolved with something like the following:\r\n\r\n```js\r\nlet elem = this.$parent;\r\nwhile (elem.$parent && !elem[func]) {\r\n    elem = elem.$parent;\r\n}\r\n```\r\n\r\nThis would travel up the component tree until it found one where the callback was defined. Of course performing this while loop _**per row**_ could lead to some gross performance penalties, so you may want to add caching of the callback afterwards.\r\n\r\nJust a thought for an improvement"},"comment":{"url":"https://api.github.com/repos/ratiw/vuetable-2/issues/comments/284169808","html_url":"https://github.com/ratiw/vuetable-2/issues/59#issuecomment-284169808","issue_url":"https://api.github.com/repos/ratiw/vuetable-2/issues/59","id":284169808,"user":{"login":"stevendesu","id":1384974,"avatar_url":"https://avatars2.githubusercontent.com/u/1384974?v=3","gravatar_id":"","url":"https://api.github.com/users/stevendesu","html_url":"https://github.com/stevendesu","followers_url":"https://api.github.com/users/stevendesu/followers","following_url":"https://api.github.com/users/stevendesu/following{/other_user}","gists_url":"https://api.github.com/users/stevendesu/gists{/gist_id}","starred_url":"https://api.github.com/users/stevendesu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevendesu/subscriptions","organizations_url":"https://api.github.com/users/stevendesu/orgs","repos_url":"https://api.github.com/users/stevendesu/repos","events_url":"https://api.github.com/users/stevendesu/events{/privacy}","received_events_url":"https://api.github.com/users/stevendesu/received_events","type":"User","site_admin":false},"created_at":"2017-03-04T18:13:06Z","updated_at":"2017-03-04T18:13:06Z","body":"Thinking about it for some time, I feel like the proper solution is instead of passing the _**name**_ of the callback, the actual callback should be passed in. This way the component is handed everything it needs to operate and does not need to go looking for it in the parent.\r\n\r\nLooking at the code, this is actually how it's written -- if a function is passed instead of a name, the function is executed. I might update the tutorial, however, to make it clear that this is possible (and also the preferred method, as it would be more performant)\r\n\r\nhttps://github.com/ratiw/vuetable-2-tutorial/blob/master/doc/lesson-06.md\r\n\r\nCurrently the tutorial only demonstrates passing a string for the callback"}}
{"actor":{"display_login":"stevendesu"}}