与Vue绑定的Javascript对象数据

时间:2016-01-18 14:04:51

标签: javascript ajax vue.js

我有一个JavaScript对象,我试图绑定到Vue视图。

我正在运行一个使用AJAX更新JavaScript对象的函数,我期望Vue绑定到JS对象并在对象更新时更新视图,但不会发生。

研究建议在Vue声明中进行AJAX调用,但由于其他限制,我宁愿不这样做。

我已经创建了一个小提琴来说明问题是什么,因为它可以在没有AJAX部分的情况下重现,也可以粘贴下面的代码。

https://jsfiddle.net/g6u2tph7/5/

提前感谢您的时间和智慧。

谢谢,

vmitchell85

的JavaScript

window.changeTheData = function (){
    externalJSSystems =  [{description: 'Baz'}, {description: 'Car'}];
    document.getElementById("log").innerHTML = 'function has ran...';
    // This doesn't update the Vue data

}

var externalJSSystems = [{description: 'Foo'}, {description: 'Bar'}];

Vue.component('systable', {
    template: '#sysTable-template',
    data() {
        return {
            systems: externalJSSystems
        };
    }
});
new Vue({
   el: 'body'
});

HTML

<systable :systems="systems"></systable>

<button type="button" onclick="changeTheData()">Change</button>
<br><br>
<div id="log"></div>
<template id="sysTable-template">
    <table>
        <thead>
            <tr>
                <th>Description</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="sys in systems">
                <td>{{ sys.description }}</td>
            </tr>
        </tbody>
    </table>
</template>

3 个答案:

答案 0 :(得分:3)

试试这个:

externalJSSystems.push({description: 'Baz'}, {description: 'Car'});

它会将新对象附加到 externalJSSystems ,视图将会更新。你的例子为什么不起作用?因为您要为 externalJSSystems 分配一个新的Array引用,但Vue仍在观看旧版本。

要实现您的目标,请不要分配新的Array实例,但要清除它。例如:

window.changeTheData = function (){
    externalJSSystems.length = 0
    externalJSSystems.push({description: 'Baz'}, {description: 'Car'});
}

答案 1 :(得分:2)

当实例化systable组件的那个实例时,Vue会添加一个&#34; Observer&#34;类到初始externalJSSystems数组 - 扩展Array的原型,为每个属性添加getter / setter,并维护Component data之间的双向绑定原始数组。 changeTheData()方法用一个全新的数组(缺少Observer)覆盖了Vue修改的externalJSSystems数组,从而破坏了双向绑定。

通过这种方式,externalJSSystems.push( … )可以正常工作,因为默认的数组方法(&#39; push&#39;,&#39; pop&#39;,&#39; shift&#39;,&#39;未移位&#39;,&#39; splice&#39;,&#39; sort&#39;和&#39;反向&#39;)已经变异,以便它们由Observer处理。

我认为你所寻找的行为的关键在于Vue组件&#34;道具&#34; - http://vuejs.org/guide/components.html#Props。事实上,您的组件标记 - <systable :systems="systems"></systable> - 似乎已经设置为将动态数据传递给Component实例。现在,:systems="systems"没有做任何事情。通过在Parent Vue范围中定义systems,并在组件注册中将systems定义为prop(s),您可以将动态数据传递到该父范围内的组件。

<强>组件

Vue.component('systable', {
  template: '#sysTable-template',
  props: {
    systems: Array
  }
});

Vue实例

var vm = new Vue({
  el: 'body',
  data: {
    systems: externalJSSystems
  }
});

你可以在这个小提琴中看到它:https://jsfiddle.net/itopizarro/ycr12dgw/

我缓存了Vue实例 - var vm = new Vue({ … }) - 因此changeTheData方法可以访问其systems数据。 这为您的外部changeTheData()方法提供了对您定义system的Vue实例的引用 - 从而为其提供了修改(无需替换或迭代添加/删除项目...)的数组数据。

答案 2 :(得分:0)

不是将系统设为数据属性,而是将其设为计算属性。像其他答案所说的那样,引用的是旧的对象。但是如果你使systems成为计算属性,它将自动监视计算中使用的任何变量(如externalJSSystems)并重新计算计算属性。

Vue.component('systable', {
template: '#sysTable-template',
computed: {
    systems() {
        return externalJSSystems;
    }
}
});