2017-03-14 25 views
0

私は流星に熱心に取り組んでいます。目標は、海の上のボートなど、車両の経路をGoogleマップに動的に表示することです。流星:オートランで私のコードが動的にならない

このライブラリはgmaps.jsと呼ばれています.npmで利用できるので(Googleマップのapiと同じように)、マップを描画するソリューションとしてこれを使用することにしました。

私は、ボタンをクリックするたびにデータベースに地理的な位置(/実行/送信)を追加するページを1つ持っています(これはテストのためにenougthです)。そして、私の他のページ(/ラン/ショー)では、そのデータをmongoから取得し、マップ上でそれを動的にプロンプ​​トします(つまり、ボタンを押してデータを追加すると、新しいパスが地図)。ここでは、コードは今のところ次のようになります。

import { Template } from 'meteor/templating'; 
import {Tracker} from 'meteor/tracker'; 
import { Meteor } from 'meteor/meteor' 
import gmaps from 'gmaps'; 
import google_maps from 'google-maps'; 

import {Mongo} from 'meteor/mongo'; 

import {Run} from './run.js'; 
import './methods.js'; 

Template.runs_show.helpers({ 
    all() { 
     return Run.find({}); 
    } 
}); 

Template.runs_show.onCreated(function() { 

    var self = this; 
    self.autorun(function() { 
     self.subscribe('allRuns',function() { 
      google_maps.KEY = "MY API KEY"; 
      google_maps.load(function(google){ 

       console.log("Google Maps loaded"); 

       // this creates a new map 
       var map = new gmaps({ 
         el: '#map-gmaps', 
         lat: -12.043333, 
         lng: -77.028333 
       }); 

       // for now , the data is on the run with {"maxSpeed" : "75"} 
       var dada = Run.findOne({"maxSpeed" : "75"}); 

       // path look like [[x1,y1],[x2,y2]] 
       var path = dada.positions; 

       // this draws a red line on the map following the points defined in path 
       map.drawPolyline({ 
        path: path, 
        strokeColor: '#FC291C', 
        strokeOpacity: 0.85, 
        strokeWeight: 6 
       }); 


       }); 
     }); 
    }); 

    }); 

だから、あなたが見ることができるように、私はオートランブロックに私のonCreated機能を入れて、それはカーソルですので、私が使用しているデータは、データベースからです、反応性もあるはずです。

反応性のあるデータは、反応性のあるブロック内にあります(自動返信ありがとう)?私の2番目のページ(このページはrun.positionsに[x、y]の新しいセットを追加する)で "send"を押すと、私の画面に新しい行が表示されることが予想されますが...。実際には、ページを手動でリロードすると、もちろん新しい行が表示されますが、これは私が正直にしたかったものではありません...

これだけです!いくつかの真の反応性を得るために何が欠けているのか?

EDIT:

このコードは部分的に動作します。私は、ページをロードする最初の時間を、にconsole.log(マップ)は、未定義を与えるが、私は一度だけリロードする必要があり、そのページが動作します私が動的にしたいものを示しています。しかし、1つのコードをリロードして再度console.log(map)を実行すると未定義となり、新しいF5が必要になります。

Template.runs_show.onCreated(function() { 

     google_maps.KEY = "MY API KEY"; 
     google_maps.load(function(google){ 
      var map = new gmaps({ 
        el: '#map-gmaps', 
        lat: -12.043333, 
        lng: -77.028333 
      }); 

      // with that, I can use the map in the onRendered 
      Template.runs_show.map = map; 
     }); 

     console.log(Template.runs_show); 

}); 

Template.runs_show.onRendered(function() { 

    var self = this; 
    self.autorun(function() { 
     self.subscribe('allRuns',function() { 
      Tracker.autorun(function(){ 

       var map = Template.runs_show.map; 

       console.log(map); 

       var dada = Run.findOne({"maxSpeed" : "75"}); 
       var path = dada.positions; 

       map.drawPolyline({ 
        path: path, 
        strokeColor: '#FC291C', 
        strokeOpacity: 0.85, 
        strokeWeight: 6 
       }); 

        // seems to not be necesary 
       //map.refresh(); 

      }); 
     }); 
    }); 

}); 

(この新しいコードでは、私はちょうどgmapsがロードされたとき、onCreatedでマップを作成し、その後、私はonRenderedですべての描画を行う。ところで、私がTemplate.xxx.mapを使用onCreatedとonRenderedの間でデータを送信するのは、私がやるべきことなのですか?)

+0

'self.autorun'の代わりに' Tracker.autorun'を使うか 'self.autoun'の代わりに' .bind(this) 'を使ってみてください。 .autorun(function(){..}。bind(this)); ' – mutdmour

+0

.bindの目的は何ですか? – xababafr

+0

で、 'this'のスコープやコンテキストの管理について説明しています。 'this'をコールバックではなく' Template'にバインドします。 [例](https:// stackoverflow。com/questions/35000844/meteor-template-autorun-is-not-a-function-when-using-es6) – mutdmour

答えて

0

このため、ネストされたテンプレートを使用してみてください。ラッパーのテンプレートは、データをサブスクライブし、サブスクリプションの準備ができたときにのみ、ネストされたテンプレートをレンダリングするように:

//wrapper template that manages subscription 
Template.wrapper.onCreated(function() { 
    this.subscribe('allRuns'); 
}); 

Template.runs_show.onRendered(function() { 
    google_maps.KEY = "MY API KEY"; 
    google_maps.load(function(google){ 
    var map = new gmaps({ 
     el: '#map-gmaps', 
     lat: -12.043333, 
     lng: -77.028333 
    }); 

    Tracker.autorun(function() { 
     // Run.find will re-trigger this whole autorun block 
     // if any of the elements of the collection gets changed or 
     // element gets created or deleted from collection 
     // thus making this block reactive to data changes 
     // this will also work with findOne in case you only want to 
     // one run only 
     var runs = Run.find({"maxSpeed" : "75"}).fetch(); 
     // map.clear() or something like that to remove all polylines 
     // before re-rendering them 
     runs.forEach(function(run){ 
     map.drawPolyline({ 
      path   : path, 
      strokeColor : '#FC291C', 
      strokeOpacity : 0.85, 
      strokeWeight : 6 
     }); 
     }); 

    }); 
    // ^^ this is pretty dumb and re-renders all items every time 
    // something more intelligent will only re-render actually 
    // changed items and don't touch those who didn't change but 
    // that will require a slightly more complex logic 

    }); 
}); 

wrapper.html:

<template name="wrapper"> 
    {{#if Template.subscriptionsReady }} 
    {{> runs_show }} 
    {{/if}} 
</template> 

P.S.これはほとんどテストしていないのでほとんどの疑似コードですので、それをガイドとして使用してください

+0

さて、私はあなたの答えを見ました。とても面白いです...私を助ける努力をしてくれて、感謝します。私は今、それをテストすることはできませんが、数日で私はできるようになりますし、何かがこのようにうまくいく場合、私はあなたに言うでしょう。とにかく、私はおそらく決してそれについてthougth、いい考えです:p – xababafr

+0

あなたは何を知っていますか?それはうまくいった!素晴らしい! – xababafr

+0

それが助けてくれてうれしい! @xababafr –

0

subscribeコールバックは反応的なコンテキストではないと思われます。 herehereの他の人のために働いたことをやってみて、あなたのonRenderedにトラッキングを入れてみてください。

Template.templateName.onRendered(function() { 
    var self = this; 
    self.autorun(function() { 
     self.subscribe('allRuns',function() { 
      Tracker.autorun(function(){ 
       ... 
      } 
     }) 
    }) 
}) 
関連する問題