在聚合物JS

时间:2018-05-04 09:56:05

标签: polymer polymer-2.x

我正在使用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"而不是"设置"但那也行不通。

有人可以建议我在这里做错了什么用户对象在DOM中没有改变?

更新

如下所述,我使用splice来更新阵列,但它仍无法正常工作。

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

3 个答案:

答案 0 :(得分: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);
        }

修改

但是,当您想编辑某些内容时,从数组中的对象创建引用,因此当您输入输入时,您将更新现有数组中的对象{{ 1}}。

我摆弄你的小提琴,现在它奏效了。我所做的是我在方法users中添加了JSON.parse(JSON.stringify())

http://jsfiddle.net/c6h2hwch/

答案 1 :(得分:0)

来自"Set a property or subproperty by path":“对象属性上的调用set不会导致Polymer获取对象子属性的更改,除非对象本身发生更改。”注意例子:

// DOES NOT WORK
this.profile.name = Alex;
this.set('profile', this.profile);

您需要将this.profile替换为新的profile对象,或更新profile的每个成员的路径。

答案 2 :(得分:0)

这不是一个可观察到的变化:

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);

这说,“在1移除foundIndex项,并在其位置插入this.user

另一个选项是创建数组的副本(使用Array.prototype.slice - 请注意slice,而不是splice)以使更改可观察:

const nextUsers = this.users.slice();
nextUsers[foundIndex] = this.user;
this.users = nextUsers;

我建议使用this.splice,因为它不能使Polymer在重新渲染时完成相同的工作。数组的dom-repeat