简体   繁体   中英

v-data-table doesn't updates on a new data

I have a object portfoliosData in a Vuex store. This object has a property metrics

  state: {
    portfoliosData: {
      performance: [],
      metrics: []
    },

When performing an action I mutate the property in the store and want to show the updates in a table.

 <div id="amsample">
  <div id="chartdiv"></div>
   <v-tabs-items  :touchless="true">
      <v-tabs-content :key="0" id="tab-1">
        <v-card flat>
          <v-card-text>
            Return Performance
            <v-data-table
              :headers="headers"
              :items="metrics"
              :custom-sort="sortPercentage"
              hide-actions
              class="elevation-1"
            >
              <template slot="items" scope="props">
                <td>{{ props.item.name }}</td>
                <td class="text-xs-right">{{ props.item.acRet }}</td>
                <td class="text-xs-right">{{ props.item.anRet }}</td>
                <td class="text-xs-right">{{ props.item.anVol }}</td>
                <td class="text-xs-right">{{ props.item.maxDd }}</td>
                <td class="text-xs-right">{{ props.item.sRatio }}</td>
                <td class="text-xs-right">{{ props.item.inRatio }}</td>
              </template>
            </v-data-table>
          </v-card-text>
        </v-card>
      </v-tabs-content>
    </v-tabs-items>
 </div>

In the component table observes the metrics variable.

data() {
      return {

        headers: [
          {text: 'Measure', value: 'name', sortable: false},
          {text: 'Accumulative Return', value: 'acRet'},
          {text: 'Annual Return', value: 'anRet'},
          {text: 'Annual Volatility', value: 'anVol'},
          {text: 'Max Drawdown', value: 'maxDd'},
          {text: 'Sharpe Ratio', value: 'sRatio'},
          {text: 'Information Ratio', value: 'inRatio'},
        ],
        metrics: []
      }
    },

When I call an action in the component I get the updated metrics from the store

//Component
  calulateMetrics(event) {
    this.$store.dispatch('performeMetricsCalculation', {dataZoomStart:event.startDate, dataZoomEnd:event.endDate}).then(() => {
      this.metrics = this.$store.getters.getMetrics;
      console.log("Calculated metric", this.metrics)
    })
  },

//actions
performeMetricsCalculation({dispatch, commit, getters}, {dataZoomStart, dataZoomEnd}) {
  //console.log("performeMetricsCalculation", dataZoomStart, dataZoomEnd)

  return new Promise((resolve, reject) => {
    dispatch('performSetRangeTime', {dataZoomStart: dataZoomStart, dataZoomEnd: dataZoomEnd}).then(() => {
      dispatch('performMetrcisUpdating').then(() => {
        commit('resetUpdateStatus')
      })
    })
    resolve()
  })
},

performMetrcisUpdating({commit}) {
  return new Promise((resolve, reject) => {
    commit('calculateMetrics')
    resolve()
  })
},

During debugging I printed the metrics variable and I see that the data differers from the initial one. But the table doesn't updates.

In mutations I use the following logic

calculateMetrics({portfoliosData, period, status}) {
  let updatedMetrics = []

  for (let s in portfoliosData.performance) {
    if (portfoliosData.performance.hasOwnProperty(s)) {
      //console.log("Calculate metrics", period.startDateIdx, period.endDateIdx)
      let port = {...portfoliosData.performance[s]}

      updatedMetrics.push({
        name: port.name,
        maxDd: maxDrawdown(port.data, period.startDateIdx, period.endDateIdx),
        acRet: accumulativeReturn(port.data, period.startDateIdx, period.endDateIdx),
        anRet: annualReturn(port.data, period.startDateIdx, period.endDateIdx),
        anVol: annualVolatility(port.data, period.startDateIdx, period.endDateIdx),
        sRatio: sharpeRatio(port.data, period.startDateIdx, period.endDateIdx),
        inRatio: informationRatio(port.data, period.startDateIdx, period.endDateIdx)
      })

      if (!status.isUpdated) {
        portfoliosData.metrics = updatedMetrics
      } else {
        Vue.set(portfoliosData, 'metrics', updatedMetrics)
      }
    }
  }
}

When I get the data without performing an action there is no problem with updating the table. However when I want to update the table the new data doesn't render, although the metrics variable changes. That looks weird.

I observe this issue only in this specific case. Also I tried to change :items="metrics" to :items=$store.getters.getMetrics but it didn't help me either.

I think you can change mutations to

calculateMetrics(state) {
  let {portfoliosData, period, status} = state // ES6 syntax
  let updatedMetrics = []

  for (let s in portfoliosData.performance) {
    if (portfoliosData.performance.hasOwnProperty(s)) {
      //console.log("Calculate metrics", period.startDateIdx, period.endDateIdx)
      let port = {...portfoliosData.performance[s]}

      updatedMetrics.push({
        name: port.name,
        maxDd: maxDrawdown(port.data, period.startDateIdx, period.endDateIdx),
        acRet: accumulativeReturn(port.data, period.startDateIdx, period.endDateIdx),
        anRet: annualReturn(port.data, period.startDateIdx, period.endDateIdx),
        anVol: annualVolatility(port.data, period.startDateIdx, period.endDateIdx),
        sRatio: sharpeRatio(port.data, period.startDateIdx, period.endDateIdx),
        inRatio: informationRatio(port.data, period.startDateIdx, period.endDateIdx)
      })


    }
  }
   portfoliosData.metrics = updatedMetrics
   state.portfoliosData = JSON.parse(JSON.stringify(portfoliosData)) // assign to new object
}

We need to create new object (I used JSON.parse(JSON.stringify()) technique) to make vuex understand data is changed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM