【问题标题】:Vue state does not sync with kendo datasourceVue 状态不与 kendo 数据源同步
【发布时间】:2020-06-12 07:50:44
【问题描述】:

我有一个 kendo 包装网格,其中本地 kendo 数据源 指向 vue 状态。 有一个按钮“更新”,它将更新状态,以便网格也将更新并且它可以工作。

但是,如果我首先单击按钮“Test”(只是对状态的赋值相同)然后单击“Update”,奇怪的是它不起作用网格没有变化。

我终于找到原因是在点击“Test”然后“Update”之后,vue状态更新了但是剑道网格数据源不会(超出意外同步)。 现在临时解决方案是我必须手动将状态分配给数据源,以便更新网格。

回购:http://dojo.telerik.com/aGENIHuW

我的问题是,为什么在点击“Test”后,kendo 网格数据源被缓存并且与 vue 状态不同步? 如果我不点击“测试”,它们会一直同步。 仅当对状态进行“相同的值分配”时才会出现问题。如果是“不同的赋值”,没问题。

<div id="vueapp">
    <kendo-datasource ref="dsDS" :data="localDataSource"></kendo-datasource>
    <kendo-grid :data-source-ref="'dsDS'">
        <kendo-grid-column :field="'ProductID'"
                           :title="'ID'"
                           :width="40"></kendo-grid-column>
        <kendo-grid-column :field="'ProductName'"></kendo-grid-column>
        <kendo-grid-column :field="'UnitPrice'"
                           :title="'Unit Price'"
                           :width="120"
                           :format="'{0:c}'"></kendo-grid-column>
        <kendo-grid-column :field="'UnitsInStock'"
                           :title="'Units In Stock'"
                           :width="120"></kendo-grid-column>
        <kendo-grid-column :field="'Discontinued'" :width="120"></kendo-grid-column>
    </kendo-grid>
    <input type="button" value="Test" @click="test" />
    <input type="button" value="Update" @click="update" />
</div>
new Vue({
    el: '#vueapp',
    data: {
        localDataSource: [{
                "ProductID": 1,
                "ProductName": "Chai",
                "UnitPrice": 18,
                "UnitsInStock": 39,
                "Discontinued": false,
            },
            {
                "ProductID": 2,
                "ProductName": "Chang",
                "UnitPrice": 17,
                "UnitsInStock": 40,
                "Discontinued": false,
            },
            {
                "ProductID": 3,
                "ProductName": "Aniseed Syrup",
                "UnitPrice": 10,
                "UnitsInStock": 13,
                "Discontinued": false,
            }
        ]
    },
    methods: {
      test: function(e) {
        this.localDataSource = JSON.parse(JSON.stringify(this.localDataSource)); //same value assignment
        console.log('test');
      },
      update: function(e) {
        this.localDataSource.splice(0, 1, this.localDataSource[1]); //replace the first object with second object
      },
    }
})

更新:

让我在下面强调我的问题:

为什么 test2() + update() => 有效!

但是 test() + update() => 不行

它们的不同只是 test2() 的值赋值 'hello'

methods: {
    test: function(e) { //same value assignment
        let ds = JSON.parse(JSON.stringify(this.localDataSource));
        this.localDataSource = JSON.parse(JSON.stringify(ds));
    },
    test2: function(e) { //different value assignment
        let ds = JSON.parse(JSON.stringify(this.localDataSource));
        ds[0]['ProductName'] = 'hello';
        this.localDataSource = JSON.parse(JSON.stringify(ds));
    },
    update: function(e) {
        this.localDataSource.splice(0, 1, this.localDataSource[1]); //replace first row with second row
    }
}

http://dojo.telerik.com/aGENIHuW/10

【问题讨论】:

    标签: vue.js kendo-ui kendo-grid kendo-datasource


    【解决方案1】:

    一旦在 data() 对象中设置了数据源,并且绑定了剑道网格,我就不会尝试编辑 localDataSource 对象。剑道网格获取您的基本数组并将其转换为具有所有扩展属性的剑道数据源,因此我将针对该新对象进行更改。

    在您的更新方法中尝试类似下面的操作 - 如果您可以通过包装器属性为网格分配一个 id,那么选择器会比我这里的更好

        let gridDS = $("div[data-role=grid]").data("kendoGrid").dataSource;
        let data = gridDS.data();
        data.splice(0,1,data[1]);
    

    顺便说一句,数据方法应该返回一个新对象,否则您可能会遇到重复组件共享同一对象的问题 所以而不是

        data:{
            localDataSource:[1,2,3]
        }
    

    我愿意

        data(){
            return {
                localDataSource:[1,2,3]
            }
        }
    

    【讨论】:

    • 乔尔感谢您的回复。太奇怪了,如果我将“this.localDataSource.splice(0, 1, this.localDataSource[1])”添加到代码的末尾,它就不能再工作了。顺便说一句,我更新了我的原始帖子以突出我的问题。
    • 所以,从技术上讲,test() 函数实例化了一个全新的对象并将 localDataSource 引用重定向到该对象,而 update() 函数改变了现有对象。因此,如果您调用 test() 然后调用 update(),则您正在更新该新对象。一旦你创建了一个新对象,你就是在告诉网格“你使用你的对象,我将使用我的”
    • 但是 test2() + update() 有效。为什么 test() + update() 不起作用?
    【解决方案2】:

    添加这个作为答案,因为 cmets 不能容纳这么多文本:

    如果您在 update() 函数之后进行数据转储: console.table(this.localDataSource) 您将看到 localDataSource 数组正在正确更新。但是剑道网格并没有意识到这一点。它仍然有自己的数据数组。如果你对剑道数据源做相应的转储,你会看到它没有被同步

       let gridDS = $("div[data-role=grid]").data("kendoGrid").dataSource;
       let data = gridDS.data();
       console.table(data);
    

    我认为正在发生的事情是这样的——因为 localDataSource 是 data() 的一个属性,Vue 会观察到它的嵌套属性的任何变化。 当它执行代码ds[0]['ProductName'] = 'hello' 时,Vue 会获取更新,查找对象的依赖关系,并重新绑定 kendo-grid 组件。

    【讨论】:

    • 当它执行代码 ds[0]['ProductName'] = 'hello' 时,假设 Vue 不会接收更新,因为此时 ds 没有指向 localDataSource。 ds 只是根据“let ds = JSON.parse(JSON.stringify(this.localDataSource))”复制了 localDataSource 的值,而不是对 localDataSource 的引用。所以这就是为什么我怀疑在这种情况下,关于“相同的赋值”是 Vue 上的异常行为。我向 kendo 发送了一封电子邮件,他们同意这很奇怪,他们调试了 DataSource,由于某些原因,Vue 似乎删除了 DataSource 可观察属性。
    猜你喜欢
    • 2015-06-20
    • 2021-09-05
    • 2021-04-14
    • 2021-08-25
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 2013-09-04
    相关资源
    最近更新 更多