在更新聚合物JS中的性能值时面临问题



我正在使用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

最新更新