目前我有一个Angular2应用程序,其中包含一个包含嵌套对象的对象。用户按照向导更新对象的任何部分,然后单击“保存”。目前,我只是将整个对象发送到服务器端进行更新。要进行更新,我从数据库中获取数据库副本,只需将客户端副本的所有字段设置到数据库副本上,无论它们是否已更改,然后保存。这意味着我还必须循环遍历所有嵌套对象并将它们从数据库中拉出并设置它们的所有属性等等。一切都得到更新,即使它没有改变。
这是我通常这样做的方式,但对于这个应用程序,我需要保留已更改的对象的审核日志。如果主对象每次更新都很难,每隔一个子对象记录它也会更新。
是否有一种优雅的方法可以确保服务器端只知道更新已更改的内容(因此只触发该对象的审核日志,并且不会浪费时间在数据库上进行更新)。
我正在考虑创建一个对象,该对象在客户端存储脏对象列表,因为用户在向导中更改了内容并将其与对象一起发送到服务器,因此我知道哪些对象需要更新。
或者我应该像现在这样将整个对象发送到服务器,并将其与原始数据库对象(通过循环遍历所有对象并进行比较)进行比较,以确定已更改的内容?
这似乎很多工作。我想知道是否有这样做的标准方法/最佳实践。
编辑2018-04-24:我刚刚发现了BreezeJS。这是我想用来实现我的目标吗?它跟踪实体及其修改后的状态,并在需要时作为更改集进行相应更新。我还应该研究其他类似的东西吗?
你可以使用包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
好的,这个怎么样..
我的2美分..
在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上的Tomato库的作者。