relationsBehavior.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import isEmpty from './isEmpty'
  2. import debounce from './debounce'
  3. /**
  4. * bind func to obj
  5. */
  6. function bindFunc(obj, method, observer) {
  7. const oldFn = obj[method]
  8. obj[method] = function(target) {
  9. if (observer) {
  10. observer.call(this, target, {
  11. [method]: true,
  12. })
  13. }
  14. if (oldFn) {
  15. oldFn.call(this, target)
  16. }
  17. }
  18. }
  19. // default methods
  20. const methods = ['linked', 'linkChanged', 'unlinked']
  21. // extra props
  22. const extProps = ['observer']
  23. export default Behavior({
  24. lifetimes: {
  25. created() {
  26. this._debounce = null
  27. },
  28. detached() {
  29. if (this._debounce && this._debounce.cancel) {
  30. this._debounce.cancel()
  31. }
  32. },
  33. },
  34. definitionFilter(defFields) {
  35. const { relations } = defFields
  36. if (!isEmpty(relations)) {
  37. for (const key in relations) {
  38. const relation = relations[key]
  39. // bind func
  40. methods.forEach((method) => bindFunc(relation, method, relation.observer))
  41. // delete extProps
  42. extProps.forEach((prop) => delete relation[prop])
  43. }
  44. }
  45. Object.assign(defFields.methods = (defFields.methods || {}), {
  46. getRelationsName: function(types = ['parent', 'child', 'ancestor', 'descendant']) {
  47. return Object.keys(relations || {}).map((key) => {
  48. if (relations[key] && types.includes(relations[key].type)) {
  49. return key
  50. }
  51. return null
  52. }).filter((v) => !!v)
  53. },
  54. debounce: function(func, wait = 0, immediate = false) {
  55. return (this._debounce = this._debounce || debounce(func.bind(this), wait, immediate)).call(this)
  56. },
  57. })
  58. },
  59. })