user6905325
user6905325

Reputation: 83

vue.js is not updating the DOM after updating the array

I read a list of items via AJAX and push it into a data Array:

loadSparepartFiles: function() {
    var vm = this;
    vm.activeSparepart.attachments = [];
    ajaxApi.loadJson('spareparts/sparepart/getFiles/'+vm.activeSparepartId, function(data) {
        for (var i = 0; i < data.files.length; i++) {
            vm.activeSparepart.attachments.push({
                filename: data.files[i]
            });
        }
    });
},

In the Vue devTools in Chrome I can see the updated data array, but the DOM list is still empty.

The template:

<div v-for="file in activeSparepart.attachments" class="uk-width-1-2 uk-margin-bottom">
    <a href="{{ baseUrl }}/download/sparepart/{{ activeSparepartId }}/{{ file.filename }}" target="hidden-frame" class="block-link">
        <i class="delete uk-icon-remove"></i>
        <i class="icon uk-icon-image"></i>
        <span class="title">
            {{ file.filename }}
        </span>
    </a>
</div>

The activeSparepart Object is initialised here:

resetSparepart: function() {
    this.activeSparepart = {
        alternates: [],
        locations: [],
        logs: [],
        usages: [],
        vendors: [],
        sparepart: {},
        attachments: []
    };
    this.activeSparepartId = 'new';
},

Vue devTools shows the following:

Upvotes: 8

Views: 9067

Answers (2)

Primoz Rome
Primoz Rome

Reputation: 11031

I think the problem is that your activeSparepart.attachments is not reactive.

Read about Change Detection Caveats in Vue: For Arrays for the short answer, or learn about Vue Reactivity in Depth.

If activeSparepart is an object and you add property attachments the attachments will not be recognised...

Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it’s possible to add reactive properties to a nested object using the Vue.set(object, key, value) method:

Vue.set(vm.activeSparepart, 'attachments', [])

Upvotes: 13

minagawah
minagawah

Reputation: 95

Remember that you define Vue.js component data as a function returning a whole new object to prevent the data been shared with other components. If you wish to modify an array, you need to first get the whole thing, make changes, and put the whole thing back again.

var list = vm.activeSparepart.attachments;
for (var i=0; i < data.files.length; i++) {
    list.push({ filename: data.files[i] });
}
vm.activeSparepart.attachments = list;

Upvotes: 0

Related Questions