JS ES6 конструирует объект с оригинальными и атрибутами, похожими на коллекции Laravel - PullRequest
0 голосов
/ 25 апреля 2019

Я пытаюсь создать расширяемый базовый класс модели, который позволит проводить различия между original и attributes, чтобы я мог создать метод 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

С помощью этого кода я создаю учетную запись, расширяя эту модель с помощью модели учетной записи:

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.original, так и this.attributes.У кого-нибудь есть рекомендации по созданию неизменяемой this.original версии объекта учетной записи, которая передается в конструктор, который затем можно использовать для сравнения с мутированным attributes?Моя конечная цель здесь - отправлять только измененные атрибуты на сервер (я использую Laravel 5.8).Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...