首页 > 解决方案 > JS ES6 构造一个具有类似于 Laravel 集合的原始和属性的对象

问题描述

我正在尝试创建一个可扩展的基模型类,它允许在 和 之间进行区分originalattributes以便我可以getDirty()在子类上创建一个方法,该方法将在对象orignal属性和任何更改的attributes. 这是到目前为止的课程:

import Vue from 'vue'

class Model {

  constructor (attributes) {
  this.original = attributes
  this.attributes = attributes

  Object.keys(this.attributes).forEach((property) => {
    Object.defineProperty(this, property, {
      get: () => this.getAttribute(property),
      set: (value) => this.setAttribute(property, value)
    })
  })
  }

  getAttribute (key) {
    return this.attributes[key]
  }

  setAttribute (key, value) {
    this.attributes[key] = value
  }

  static fetchById (id) {
    if (!id) {
      throw new Error('Cannot fetch without id')
    }

  return Vue.prototype.$http
    .get(this.endpoint + id)
    .then(response => {
      return new this(response.data)
    })
    .catch(error => {
      console.error(error)
    })
  }
}

export default Model

使用此代码,我通过使用 Account 模型扩展此模型来创建一个帐户:

import Model from './Model'
import Vue from 'vue'

class Account extends Model {

  static endpoint = '/api/accounts/'

  getOwner () {
    if (this.company_owner_uuid) {
      return 'company'
    }
    return 'person'
  }

  getDirty = () => {
    // This log is showing the changed name from the component input, rather than the original
    console.log(this.original.person_owner.first_name)
    const diff = Object.keys(this.original).reduce((diff, key) => {
      if (this.attributes[key] === this.original[key]) return diff
      return {
        ...diff,
        [key]: this.original[key]
      }
    }, {})

    return diff
  }

  update () {
     return Vue.prototype.$http
       .put(`${Account.endpoint}/${this.account_uuid}`, this.getDirty())
       .then(response => {
         console.log(response)
          return response.data
       })
       .catch(error => {
         console.error(error)
       })
  }
}

export default Account

在我的组件中:

Account.fetchById(this.id).then(account => {
  this.account = account
})
  .catch(error => {
    console.error(error)
  })
  .then(() => {
    // hide loading or whatever after promise is fully resolved...
  })

除了我对帐户进行更改之外,这一切都有效,它同时改变了this.originalthis.attributes。是否有人建议创建this.original帐户对象的不可变版本,该版本传递给构造函数,然后可用于与 mutated 进行比较attributes?我的最终目标是只将任何修改后的属性发送到后端(我使用的是 Laravel 5.8)。谢谢!

标签: javascriptlaraveloopvue.jsecmascript-6

解决方案


推荐阅读