2016-09-22 21 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

はちょうどあなたのAPIまたは何にAJAX呼び出しを作る(計算非同期を使用すること。それを非問題を作る必要があります)、あなたは結果があなたのAJAX応答 –

+0

@PrimozRomeから内容を返す取得するとき次に、コンテンツを更新する方法は? – Ovilia

+0

あなたのアプリの仕組みが分かりませんが、私はフィルタでこれをやりません...あなたがIDを持っていれば、そのIDのユーザ名を返すためにあなたのAPIへのajaxコールを処理するためにVueを使ってください。 –

答えて

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>

関連する問題