2017-02-20 110 views
1

當vm數據更新時,我無法讓我的計算過濾器值更新。在我的情況下,我有一些時間datetime存儲在VM模型中的UTC。然後我有一個過濾器,它顯示那些使用時刻格式化爲時區的時間。然後,如果用戶想要切換時區,但希望切換時區,但切換時區時,濾波值不會相應更新。我錯過了什麼讓他們被動?此外,它甚至沒有使用我的默認值selectedTz: 'America\Los_Angeles'(您會注意到,儘管此默認設置,它始終將TZ +0(UTC)顯示爲所有時間)。vue2無功濾波器值?

var app = new Vue({ 
 
     el: '#app', 
 
     data: { 
 
      games: [{start_time: '2017-01-23 21:00:00'}, {start_time: '2017-01-23 22:00:00'}, {start_time: '2017-01-23 23:00:00'}], 
 
      selectedTz: 'America/Los_Angeles' 
 
     }, 
 
     methods: { 
 
      switchToEast: function() { 
 
       this.selectedTz = 'America/New_York' 
 
      }, 
 
      switchToWest: function() { 
 
       this.selectedTz = 'America/Los_Angeles' 
 
      } 
 
     }, 
 
     filters: { 
 
      usertz: function (date) { 
 
       var tz = this.selectedTz 
 
       var x = new moment.tz(date, 'Etc/UTC') 
 
       x.tz(tz) 
 
       return x.format('MMM Do @ h:mm a Z') 
 
      } 
 
     } 
 
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.11/moment-timezone-with-data.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script> 
 
<div id="app"> 
 
    <p class="text-right">All times are in {{ selectedTz }}</p> 
 
    <div class="text-right"> 
 
     <button class="button" @click="switchToEast()">East</button> 
 
     <button class="button" @click="switchToWest()">West</button> 
 
    </div> 
 
    <p v-for="game in games"> 
 
     {{ game.start_time | usertz }} 
 
    </p> 
 
</div>

回答

1

我有這樣的帶過濾器的一個問題了。無法用濾波器解決它,並決定用計算的屬性來完成它。在我看來,過濾器不能處理太多的計算。文檔本身說

過濾器主要設計用於文本轉換的目的

嘗試像我這樣,它應該工作。

var app = new Vue({ 
 
     el: '#app', 
 
     data: { 
 
      games: [{start_time: '2017-01-23 21:00:00'}, {start_time: '2017-01-23 22:00:00'}, {start_time: '2017-01-23 23:00:00'}], 
 
      selectedTz: 'America/Los_Angeles' 
 
     }, 
 
     methods: { 
 
      switchToEast: function() { 
 
       Vue.set(this, 'selectedTz', 'America/New_York') 
 
      }, 
 
      switchToWest: function() { 
 
       Vue.set(this, 'selectedTz', 'America/Los_Angeles') 
 
      } 
 
     }, 
 
     computed: { 
 
      filteredGames: function() { 
 
       var filteredList = [] 
 
       for (i = 0; i < this.games.length; i++) { 
 
        var x = new moment.tz(this.games[i].start_time, 'Etc/UTC') 
 
        x.tz(this.selectedTz) 
 
        filteredList.push({start_time: x.format('MMM Do @ h:mm a Z')}) 
 
       } 
 
       return filteredList 
 
      } 
 
     } 
 
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.11/moment-timezone-with-data.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script> 
 
<div id="app"> 
 
    <p class="text-right">All times are in {{ selectedTz }}</p> 
 
    <div class="text-right"> 
 
     <button class="button" @click="switchToEast()">East</button> 
 
     <button class="button" @click="switchToWest()">West</button> 
 
    </div> 
 
    <p v-for="game in filteredGames"> 
 
     {{ game.start_time }} 
 
    </p> 
 
</div>

+0

我認爲這種方法,但它似乎「不太高雅」,但我想,如果過濾器將不會工作方式我必須這樣做。謝謝! – Drew

+1

我同意你的意見。在我看來,能夠在這裏使用過濾器也會更冷。不過,我認爲它不會奏效。如果您在tz的過濾器中執行console.log,您會看到它未定義。這太遺憾了,因爲我很想用濾鏡做更多。 – Ozan

+1

它更優雅的過濾器,你可以使用它...但唯一的事情是相關的,那就是格式...不改變時區,這是更有針對性的計算屬性... – cefigueiredo

1

雖然這被標記爲正確運行的答案... ...將其委託給計算機屬性變換日期和格式呈現的工作。雖然格式應該是過濾器的工作。

更改對所選屬性作出反應的時區,實際上是計算屬性的工作。但是您可以讓計算屬性將所有日期轉換爲Moment.js對象,並僅使用過濾器來格式化日期的呈現......這是過濾器的確切工作。

var app = new Vue({ 
 
    el: '#app', 
 
    data: { 
 
     games: [{start_time: '2017-01-23 21:00:00'}, {start_time: '2017-01-23 22:00:00'}, {start_time: '2017-01-23 23:00:00'}], 
 
     selectedTz: 'America/Los_Angeles' 
 
    }, 
 
    methods: { 
 
     switchToEast: function() { 
 
      Vue.set(this, 'selectedTz', 'America/New_York') 
 
     }, 
 
     switchToWest: function() { 
 
      Vue.set(this, 'selectedTz', 'America/Los_Angeles') 
 
     } 
 
    }, 
 
    computed: { 
 
     filteredGames: function() { 
 
      var filteredList = [] 
 
      for (var game of this.games) { 
 
       var start_time = new moment.tz(game.start_time, 'Etc/UTC') 
 
       start_time.tz(this.selectedTz) 
 

 
       game.start_time = start_time 
 
       filteredList.push(game) 
 
      } 
 

 
      return filteredList 
 
     } 
 
    }, 
 
    filters: { 
 
     datetime: function(date) { 
 
      return date.format('MMM Do @ h:mm a Z') 
 
     } 
 
    } 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.11/moment-timezone-with-data.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script> 
 
<div id="app"> 
 
    <p class="text-right">All times are in {{ selectedTz }}</p> 
 
    <div class="text-right"> 
 
     <button class="button" @click="switchToEast()">East</button> 
 
     <button class="button" @click="switchToWest()">West</button> 
 
    </div> 
 
    <p v-for="game in filteredGames"> 
 
     {{ game.start_time | datetime }} 
 
    </p> 
 
</div>

+0

這就是也是一個很好的解決方案,昨天我更多地考慮它之後,我完全同意你的陳述 – Drew

0

過濾器可以採取額外的參數。如果將所有無功變量從函數體移動到它應該工作的參數。例如:

<template> 
    {{ message | filter(data) }} 
</template> 

<script> 
    export default { 
    filters: { 
     filter(message, data) { 
     return `Message: ${message}, Data: ${data}`; 
     }, 
    }, 

    data() { 
     return { 
     data: "Try changing me!", 
     }; 
    }, 

    props: { 
     message: String, 
    }, 
    }; 
</script> 

或者在你的榜樣:

var app = new Vue({ 
 
     el: '#app', 
 
     data: { 
 
      games: [{start_time: '2017-01-23 21:00:00'}, {start_time: '2017-01-23 22:00:00'}, {start_time: '2017-01-23 23:00:00'}], 
 
      selectedTz: 'America/Los_Angeles' 
 
     }, 
 
     methods: { 
 
      switchToEast: function() { 
 
       this.selectedTz = 'America/New_York' 
 
      }, 
 
      switchToWest: function() { 
 
       this.selectedTz = 'America/Los_Angeles' 
 
      } 
 
     }, 
 
     filters: { 
 
      usertz: function (date, tz) { 
 
       var x = new moment.tz(date, 'Etc/UTC') 
 
       x.tz(tz) 
 
       return x.format('MMM Do @ h:mm a Z') 
 
      } 
 
     } 
 
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.11/moment-timezone-with-data.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js"></script> 
 
<div id="app"> 
 
    <p class="text-right">All times are in {{ selectedTz }}</p> 
 
    <div class="text-right"> 
 
     <button class="button" @click="switchToEast()">East</button> 
 
     <button class="button" @click="switchToWest()">West</button> 
 
    </div> 
 
    <p v-for="game in games"> 
 
     {{ game.start_time | usertz(selectedTz) }} 
 
    </p> 
 
</div>