更新聚合物 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 来更新阵列,但它仍然无法正常工作。

JSfiddle - https://jsfiddle.net/ansumanmishra/8490y4q8/1/

来自"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())

http://jsfiddle.net/c6h2hwch/