2017-02-20 54 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>