使用Array Proxy时,我需要帮助解决有关* ngFor的问题 . 我需要存档的内容 - >我们想用PATCH提交数据,只发送已更改的属性 . 使用简单的值(如字符串或数字)很容易,但是当我们点击某些内容时,它很棘手 . 我从“在变化”库中获得灵感,但不得不为我们的用例更新它 .
模型示例:
User{
name:'test',
age:'43',
phones:[
'+123 123456789','+321 098765432'
],
address:[
{street:'short',city:'Prague',zip:'12345'},
{street:'third',city:'London':zip:'98765'}
]
}
我的代理处理程序
const createProxy = function (value: any): any {
let blocked = false;
const handler = {
get: (target: any, property: PropertyKey, receiver?: any): any => {
const desc = Object.getOwnPropertyDescriptor(target, property);
const value = Reflect.get(target, property, receiver);
if (desc && !desc.writable && !desc.configurable) return value;
try {
return new Proxy(target[property], handler);
} catch (error) {
return value;
}
},
defineProperty: (target: any, property: string, descriptor: PropertyDescriptor): boolean => {
const result = Reflect.defineProperty(target, property, descriptor);
if (!blocked) {
updateMetadata(self, originalTarget);
}
return result;
},
deleteProperty: (target: any, property: PropertyKey): boolean => {
const result = Reflect.deleteProperty(target, property);
if (!blocked) {
updateMetadata(self, originalTarget);
}
return result;
},
apply: (target: any, thisArg: any, argumentsList: ArrayLike<any>): any => {
if (BLACKLIST.indexOf(target.name) > -1) {
blocked = true;
const result = false;
if (target.name === 'splice') {
const result = Reflect.apply(Array.prototype.splice, thisArg, argumentsList);
} else {
const result = Reflect.apply(target, thisArg, argumentsList);
}
updateMetadata(self, originalTarget);
blocked = false;
return result;
}
return Reflect.apply(target, thisArg, argumentsList);
}
};
originalTarget = value;
proxy = new Proxy(value, handler);
return proxy;
};
我需要捕获地址数组的更改并将其标记为已更改,但是当我向数组添加新地址时,还要将其标记为已更改,删除或更改一个嵌套属性(例如street) .
我解决了如何存储这些更改并使用一个“级别”实体进行测试 .
对于具有数组或其他嵌套对象的属性,我尝试了Proxy . 使用模拟模型,它就像一个魅力 . 但是当我使用它与实际形式时,我遇到问题* ngFor ...如果我试图显示地址的输入,它最终会在无限循环的getter中,我不得不使用任务管理器来杀死那个页面 . 如果我省略ngFor和manualy显示一个地址的输入(user.address [0] ...)它没关系,甚至阴道变化也像预期的那样工作 .