更新聚合物 JS 中的 属性 值时遇到问题
Facing issues while updating the property value in polymer JS
我正在使用 Polymer js 创建一个非常简单的 CRUD 应用程序,但在编辑记录时遇到一些问题。
这是 add/edit 的代码:
_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 中没有改变吗?
更新:
按照下面的建议,我正在使用 splice 来更新阵列,但它仍然无法正常工作。
来自"Set a property or subproperty by path":"calling set on an object property won't cause Polymer to pick up changes to the object's subproperties, unless the object itself changes."注释示例:
// DOES NOT WORK
this.profile.name = Alex;
this.set('profile', this.profile);
您需要用新的 profile
对象替换 this.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
。
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]
你最终只会得到与上面相同的结果:Polymer 用自己检查数组。使用 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
.
我 fiddle 和你的 fiddle 交流过,现在可以了。我所做的是我也在方法 _editUser()
中添加了 JSON.parse(JSON.stringify())
。
我正在使用 Polymer js 创建一个非常简单的 CRUD 应用程序,但在编辑记录时遇到一些问题。
这是 add/edit 的代码:
_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 中没有改变吗?
更新:
按照下面的建议,我正在使用 splice 来更新阵列,但它仍然无法正常工作。
来自"Set a property or subproperty by path":"calling set on an object property won't cause Polymer to pick up changes to the object's subproperties, unless the object itself changes."注释示例:
// DOES NOT WORK
this.profile.name = Alex;
this.set('profile', this.profile);
您需要用新的 profile
对象替换 this.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
。
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]
你最终只会得到与上面相同的结果:Polymer 用自己检查数组。使用 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
.
我 fiddle 和你的 fiddle 交流过,现在可以了。我所做的是我也在方法 _editUser()
中添加了 JSON.parse(JSON.stringify())
。