3
votes

It's difficult for me to lift out a chunk of code from my application to demonstrate this problem, so I hope merely my describing it it will be clear enough to elicit some useful feedback.

I have a table of products, populated from an array returned by an AJAX call. As part of the call, I add another property to each object in the array:

  _.each(this.productList, (product, index) => {
      product.selected = true;
  });

In my table HTML I have this:

<tr v-for="(product, index) in this.productList" :data-code="product.code">
          <td class='selected'>

            <input type="checkbox" :name="'selected'+index" v-model="product.selected">
          </td>
etc.

So the checkboxes use 'product.selected' as the model, and this has been set to true for each item in the array, hence the checkbox for each line is initially checked. I can click on the checkbox and it updates the underlying 'product.selected' property accordingly. All well and good so far.

My problem is with using a 'toggleSelection' function, fired by clicking a button, which is intended to check or uncheck all the checkboxes:

  toggleSelection(){
    this.allSelected = !this.allSelected; //initially set to true in data object
    _.each(this.productList, (product, index) => {
      product.selected = this.allSelected;
    });
  },

This would appear to do more or less the same as the initial AJAX call, i.e., loop through the productList array and set the 'selected' property of each product object in the array. And I can see from using the Vue dev tools in Chrome that it is doing exactly this, setting 'product.selected' to either true or false. The problem is, though, that it does not update the user interface - the checkboxes all remain checked even though the property each has been bound to has been changed from true to false.

This doesn't make any kind of sense to me. Why are the checkboxes not getting unchecked when the bound objects are changed?

2
This should be working. Are you binding productList or any of the elements in that array anywhere else? How do you initially set productList? It's not a computed property, right?thanksd
productList is in data, as []. I assign it via 'this.productList=data.productList' in the AJAX call. I'm not binding the productList anywhere else, no. As I said, the binding works the first time but not with updates to the array, which I don't understand.John Moore
Not sure why it is not updating. I couldn't see any issues at your code. Please have a look at this fiddle it's your code but it's fully functional. Maybe you can see what's different compared to your code.AWolf
Does it work with Firefox ? I have this pb with Chrome only, it is working in Firefox (v58, Nightly).Ehvince

2 Answers

1
votes

I know its too late but it might help someone I had the same issue looked in the documentation didn't find anything

playing around with the code i found that there is a problem updating the DOM when bounded to new properties added to the orignal object "In your case the selected property"

my solution was load the data in new array then add the new properties to the same array then copy the new array to your array "declared in data object in your case this.productList"

var arr = []
this.loaddata(arr);    //this for example loads data from ajax call ,axios or whatever 
  _.each(arr, (product, index) => {
      product.selected = true;
  };

this.productList = arr.slice(); //copy the array 

I don't know if its an issue in Vue

0
votes

Replace product.selected = true; with Vue.set(product,selected,true);

If selected is not set at init, it will be falsy, but it will not be reactive.

Also Vue.set(product, selected, this.allSelected).