从客户端向nodejs发送对象的更新

时间:2018-03-02 08:52:51

标签: node.js design-patterns angular-cli

目前我有一个Angular2应用程序,其中包含一个包含嵌套对象的对象。用户按照向导更新对象的任何部分,然后单击“保存”。目前,我只是将整个对象发送到服务器端进行更新。要进行更新,我从数据库中获取数据库副本,只需将客户端副本的所有字段设置到数据库副本上,无论它们是否已更改,然后保存。这意味着我还必须循环遍历所有嵌套对象并将它们从数据库中拉出并设置它们的所有属性等等。即使没有改变,一切都会得到更新。

这是我通常这样做的方式,但是对于这个应用程序,我需要保留已更改对象的审核日志。如果主对象每次更新,每隔一个子对象记录它也会更新,这将很难。

是否有一种优雅的方法可以确保服务器端只知道更新已更改的内容(因此只触发该对象的审核日志,并且不会浪费时间在数据库上进行更新)。

我正在考虑创建一个对象,该对象在客户端存储脏对象列表,因为用户在向导中更改了内容并将其与对象一起发送到服务器,因此我知道哪些对象需要更新。< / p>

或者我应该像现在这样将整个对象发送到服务器,并将其与原始数据库对象(通过循环遍历所有对象并进行比较)进行比较,首先确定已更改的内容?

这似乎很多工作。我想知道是否有这样做的标准方法/最佳实践。

编辑2018-04-24:我刚刚发现了BreezeJS。这是我想用来实现我的目标吗?它跟踪实体及其修改后的状态,并在需要时作为更改集进行相应更新。还有其他类似的东西我应该研究一下吗?

3 个答案:

答案 0 :(得分:3)

您可以使用包deep-diff

var diff = require('deep-diff').diff;

var lhs = {
  name: 'my object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'elements']
  }
};

var rhs = {
  name: 'updated object',
  description: 'it\'s an object!',
  details: {
    it: 'has',
    an: 'array',
    with: ['a', 'few', 'more', 'elements', { than: 'before' }]
  }
};

var differences = diff(lhs, rhs);

以下是differences对象结构

[ { kind: 'E',
    path: [ 'name' ],
    lhs: 'my object',
    rhs: 'updated object' },
  { kind: 'E',
    path: [ 'details', 'with', 2 ],
    lhs: 'elements',
    rhs: 'more' },
  { kind: 'A',
    path: [ 'details', 'with' ],
    index: 3,
    item: { kind: 'N', rhs: 'elements' } },
  { kind: 'A',
    path: [ 'details', 'with' ],
    index: 4,
    item: { kind: 'N', rhs: { than: 'before' } } } ]

<强>差异

差异被报告为一个或多个更改记录。变更记录具有以下结构:

kind - indicates the kind of change; will be one of the following:
   N - indicates a newly added property/element
   D - indicates a property/element was deleted
   E - indicates a property/element was edited
   A - indicates a change occurred within an array
path - the property path (from the left-hand-side root)
lhs - the value on the left-hand-side of the comparison (undefined if kind === 'N')
rhs - the value on the right-hand-side of the comparison (undefined if kind === 'D')
index - when kind === 'A', indicates the array index where the change occurred
item - when kind === 'A', contains a nested change record indicating the change that occurred at the array index

答案 1 :(得分:0)

好的,这个怎么样..

  1. 不是在代码级别处理此问题,而是为什么不像现在这样发送完整对象。

  2. 在数据库中,您可以在相关的表上设置触发器,以便在更新发生之前触发。这样,您就可以更新数据以及来自外部世界的新数据。

  3. 处理那里的决定,关于审核什么,拒绝什么等。如果您发现某些内容正在更新,那么您甚至可以拒绝整个更新。

  4. 我的2美分..

答案 2 :(得分:0)

在github上使用像Tomato这样的实体库。

它是一个java库,它像普通的基于实体的持久性机制一样工作,除了你不需要除了单个提供的实体之外的任何实体。单个提供的Entity类可以从任何数据库中任何模式的任何表或表层次结构中加载和保存数据。在代码中它看起来像这样......

Entity e = Entity.createEntityOrView(schema.tablename);
e.setValue("id", 5);
e.load();

或加载记录集......

e.setFilter("name = 'rodney');
e.load();

实体类自动知道值何时变脏,因此将整个实体标记为脏。它还知道实体是从表中加载还是新的(换句话说,你总是调用save(),但它会知道是执行INSERT还是UPDATE)。

由于所有更改都是通过名为save()的Entity类中的单个方法保存的,因此可以在自定义Entity类中轻松覆盖此方法,从而允许您修改save()之前和之后发生的事情。在您的自定义实体类中,您将能够输出详细的审计数据,包括表格,主键以及确切更改的值。

通过单个提供的Web服务,可以在任何使用JSON的地方使用Tomato进行即时数据库满足,例如angular或vue(以及任何非java代码)。

查看github上的番茄库!

我是github上番茄库的作者。