我正在使用Polymer js创建一个非常简单的CRUD应用程序,但在编辑记录时遇到了一些问题。
以下是添加/编辑的代码:
_addTodo() {
if(this.user.id) {
let foundIndex = this.users.findIndex( x => x.id === this.user.id);
this.users[foundIndex] = this.user;
this.set('users', this.users);
console.log(this.users);
}
else {
this.user.id = Math.floor((Math.random() * 100000) + 1);
this.push('users', this.user);
}
this.user = {};
}
虽然我可以看到用户对象中的值在浏览器控制台中发生了变化,但在 DOM/UI 中没有改变。
如果我使用如下所示的静态用户对象,那么它可以工作:
_addTodo() {
if(this.user.id) {
var users = [
{
id: 1,
name: 'xyz',
age: 21
},
{
id: 2,
name: 'xyz123',
age: 5
}
]
this.set('users', users);
console.log(this.users);
}
else {
this.user.id = Math.floor((Math.random() * 100000) + 1);
this.push('users', this.user);
}
this.user = {};
}
即使我使用了"notifyPath"而不是"set",但这也不起作用。
任何人都可以建议我在这里做错了什么,用户对象在 DOM 中没有被更改?
更新:
如下所述,我正在使用拼接来更新数组,但它仍然不起作用。
JSfiddle - https://jsfiddle.net/ansumanmishra/8490y4q8/1/
this.users[foundIndex] = this.user; this.set('users', this.users);
更新 DOM 需要性能。每当使用set
时,Polymer dirty 都会检查数组中的每个值,但您已经将数组设置为新值,因此当它比较时(基本上,它与自身进行比较(,Polymer 不会检测到任何更新,因此不会更新 DOM。
但是,您不能将其作为解决方案:var newUserArr = this.users
,然后修改newUserArr
,因为对象和数组仅创建对彼此的引用。
var a = [1]
var b = a
b[0] = 2
console.log(a) // gives [2]
你最终只会得到与上面相同的事情:聚合物脏检查阵列本身。使用 JSON.stringify 删除引用,然后设置新数组。我一直使用这种方法。
if(this.user.id) {
let foundIndex = this.users.findIndex( x => x.id === this.user.id);
// Remove references
var newUserArr = JSON.parse(JSON.stringify(this.users)));
newUserArr[foundIndex] = this.user;
this.set('users', newUserArr);
}
编辑
但是,当您想要编辑某些内容时,您还会从数组中的对象创建引用,因此当您键入输入时,您将更新现有数组中的对象users
。
我摆弄了你的小提琴,现在它起作用了。我所做的是我也在方法中添加了JSON.parse(JSON.stringify())
_editUser()
。
http://jsfiddle.net/c6h2hwch/
从"按路径设置属性或子属性":"对对象属性调用 set 不会导致 Polymer 获取对对象子属性的更改,除非对象本身发生了更改。注意示例:
// DOES NOT WORK
this.profile.name = Alex;
this.set('profile', this.profile);
您需要将this.profile
替换为新的profile
对象,或更新profile
的每个成员的路径。
这不是一个可观察到的变化:
this.users[foundIndex] = this.user;
this.set('users', this.users);
您正在修改this.users
指向的数组(以 Polymer 无法检测到的方式(,然后将this.users
设置为同一数组 —this.set('users', this.users)
与this.users = this.users
相同的操作。
您有几个选择。一种是使用this.splice
:
this.splice('users', foundIndex, 1, this.user);
这说,"在foundIndex
处删除1
项目并在其位置插入this.user
。
另一种选择是创建数组的副本(使用Array.prototype.slice
— 请注意,这是slice
,而不是splice
(以使更改可观察:
const nextUsers = this.users.slice();
nextUsers[foundIndex] = this.user;
this.users = nextUsers;
我建议this.splice
,因为它不会使 Polymer 在重新渲染时做那么多工作,例如数组的dom-repeat
。