2016-09-22 2691 views
0

我有一个过滤器可以将带有id的内容转换为用户名。例如,它将Thank you @id-3124324 !转换为Thank you @Jack !Vue.js过滤器中的异步数据

var filter = function (content) { 
    var re = /\[email protected](id\-\d+)\s/g; 
    var matches = []; 
    var lastMatch = re.exec(content); 
    while (lastMatch !== null) { 
     matches.push(lastMatch[1]); // uid being mentioned 
     lastMatch = re.exec(content); 
    } 

    // TODO: query user name from matched id 

    // replace id with user name 
    // fake usernames here 
    var usernames = ['Random Name']; 
    for (var i = 0; i < usernames.length; ++i) { 
     content = content.replace(new RegExp(matches[i], 'g'), usernames[i]); 
    } 

    return content; 
}; 

Vue.filter('username', filter); 

但在我的情况下,usernames应该通过带有id的查询的AJAX来实现。我应该怎么做?

+0

只是做一个AJAX调用您的API或什么,当你得到的结果,从你的Ajax响应 –

+0

@PrimozRome返回内容那么如何更新内容? – Ovilia

+0

不知道你的应用程序如何工作,但我不会用过滤器做到这一点......如果你有ID,只需使用Vue处理ajax调用你的API以返回该ID的用户名。 –

回答

0

你可以用一个过滤器来做任何事情,你可以用计算器来做。在Vue 2.0中,不会有过滤器,所以您需要使用计算器。

异步获取数据到一个计算是一个有点凌乱的问题,这就是为什么有vue-async-computed plugin。难点在于计算器在尚未完成数据提取时必须同步返回一个值。

解决方案是让计算所得取决于获取数据的缓存。如果所需值不在缓存中,则计算会启动异步进程以获取它并返回一些占位符值。当进程向缓存添加值时,计算结果应该注意到缓存中的更改并返回完整值。

在下面的演示中,我不得不做一个辅助变量,trigger,我在计算中引用它,所以我知道有更新。获取过程增加trigger,这会触发计算重新评估。在decodedIds中添加或更新值时,计算不会注意到。可能有更好的方法来解决这个问题。 (使用异步计算应该让一个非问题。)

vm = new Vue({ 
 
    el: 'body', 
 
    data: { 
 
    messages: [ 
 
     'Thank you @id-3124324!' 
 
    ], 
 
    decodedIds: {}, 
 
    trigger: 0 
 
    }, 
 
    computed: { 
 
    decodedMessages: function() { 
 
     return this.messages.map((m) => this.decode(m, this.trigger)); 
 
    } 
 
    }, 
 
    methods: { 
 
    decode: function(msg) { 
 
     var re = /@(id\-\d+)/g; 
 
     var matches = msg.match(re); 
 
     for (const i in matches) { 
 
     const p1 = matches[i].substr(1); 
 
     if (!(p1 in this.decodedIds)) { 
 
      // Indicate name is loading 
 
      this.decodedIds[p1] = '(...)'; 
 
      // Mock up fetching data 
 
      setTimeout(() => { 
 
      this.decodedIds[p1] = 'some name'; 
 
      ++this.trigger; 
 
      }, 500); 
 
     } 
 
     } 
 
     return msg.replace(re, (m, p1) => this.decodedIds[p1]); 
 
    } 
 
    } 
 
}); 
 

 
setTimeout(() => { 
 
    vm.messages.push('Added @id-12345 and @id-54321.'); 
 
}, 1500);
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script> 
 
<div v-for="message in decodedMessages"> 
 
    {{message}} 
 
</div>