3

Jade テンプレートに Google マップを実装しようとしています。KeystoneJS を CMS として使用して、マップにマーカーとして追加したい多数の「プロファイル」(基本的には住所を持つ人々) を持っています。

block js
  script.
        var map;
        function initialize() {
            var mapOptions = {
              center: new google.maps.LatLng(51.0360272, 3.7359072),
              zoom: 8
            };
            map = new google.maps.Map(document.getElementById("map-canvas"),
                mapOptions);

        }

        google.maps.event.addDomListener(window, 'load', initialize);

block content
   .container
       script(src='https://maps.googleapis.com/maps/api/js?key=<GOOGLE_API_KEY>&sensor=false')

     if data.profiles
        each profile in data.profiles
            #{new google.maps.Marker({position: new google.maps.LatLng(profile.address.geo[1], profile.address.geo[0]), map: map, title: profile.name.full})}

    div(id="map-canvas", style="width:100%; height:700px;")

マップは正しく表示されますが、「各」コード ブロックを追加すると、「未定義のプロパティ「マップ」を読み取れません」というエラーが表示されます。

Jadeの「それぞれ」で実行されるjsコードを追加するにはどうすればよいですか?

4

2 に答える 2

6

あなたは本当に近いです。唯一の問題は、変数の内部、つまり#{this_stuff}すべてgooglejade のコンテキストで実行されることです (これはクライアント側であるため、オブジェクトはありません)。

ここでは、サーバー側クライアント側の 2 つのまったく異なる JavaScript 環境を扱っているため、少し注意が必要です。

したがって、クライアント側で実行される JavaScript コードに、jade のサーバー側変数を出力する必要があります。

関連する注意事項として、スクリプト ブロックで Jade 変数構文を使用できますが、他のこと (ループなど) を行うことはできません。

まず、すべてのscriptタグがjsブロック内にあるようにクリーンアップして (例の KeystoneJS テンプレートを使用していると仮定すると、<body>タグの下部になります)、それらのプロファイルが正しく生成されるようにします。

block js
    script(src='https://maps.googleapis.com/maps/api/js?key=<GOOGLE_API_KEY>&sensor=false')
    script.
        var map;
        function initialize() {
            var mapOptions = {
                center: new google.maps.LatLng(51.0360272, 3.7359072),
                zoom: 8
            };
            map = new google.maps.Map(document.getElementById("map-canvas"),
                mapOptions);
        }

        google.maps.event.addDomListener(window, 'load', initialise);

    if data.profiles
        each profile in data.profiles
            script.
                new google.maps.Marker({
                    position: new google.maps.LatLng(#{profile.address.geo[1]}, #{profile.address.geo[0]}),
                    map: map,
                    title: "#{profile.name.full}"
                });

block content
   .container
        div(id="map-canvas", style="width:100%; height:700px;")

これは近づいています (そして Jade はあなたが今期待しているものを生成します)、関数が実行される前にマーカーをマップに追加する可能性があるため、(まだ) 機能しません。initialize

また、値をエスケープしていないため"、名前に文字が含まれていると構文エラーが発生します。

より堅牢な方法は、クライアント側の配列にデータを入力し、マップが作成された後にそれをループすることです。JSON.stringifyまた、値が適切にエスケープされていることを確認するためにも使用します。

block js
    script(src='https://maps.googleapis.com/maps/api/js?key=<GOOGLE_API_KEY>&sensor=false')
    script.
        var map,
            profiles = [];

        function initialize() {
            var mapOptions = {
                center: new google.maps.LatLng(51.0360272, 3.7359072),
                zoom: 8
            };
            map = new google.maps.Map(document.getElementById("map-canvas"),
                mapOptions);

            for (var i = 0; i < profiles.length; i++) {
                new google.maps.Marker({
                    position: new google.maps.LatLng(profiles[i].geo[1], profiles[i].geo[0]),
                    map: map,
                    title: profiles[i].name
                });
            }
        }

        google.maps.event.addDomListener(window, 'load', initialise);

    if data.profiles
        each profile in data.profiles
            script.
                profiles.push({
                    geo: !{JSON.stringify(profile.address.geo)},
                    name: !{JSON.stringify(profile.name.full)}
                });

block content
   .container
        div(id="map-canvas", style="width:100%; height:700px;")

JSON がエスケープされないように !{variable} への変更に注意してください

最後に、jade テンプレートではなく、ビューのprofilesルート ファイルで配列を構築することをお勧めします。.jsこれは非常にクリーンで、ページに大量の<script>タグを配置することはありません。

したがって、あなたのルートは次のようになります(私はあなたにアイデアを与えるためにかなりのことを想定しており、アンダースコアを使用してバニラJavaScriptよりもコードをきれいにしています)

var keystone = require('keystone'),
    _ = require('underscore');

exports = module.exports = function(req, res) {

    var view = new keystone.View(req, res),
        locals = res.locals;

    // Load the profiles
    view.query('profiles', keystone.list('Profile').model.find());

    // Create the array of profile markers
    view.on('render', function(next) {
        locals.profileMarkers = locals.profiles ? _.map(locals.profiles, function(profile) {
            return { geo: profile.address.geo, name: profile.name.full };
        }) : [];
        next();
    });

    // Render the view
    view.render('profiles');

}

次に、ビュー テンプレートで:

block js
    script(src='https://maps.googleapis.com/maps/api/js?key=<GOOGLE_API_KEY>&sensor=false')
    script.
        var profileMarkers = !{JSON.stringify(profileMarkers)},
            map;

        function initialize() {
            var mapOptions = {
                center: new google.maps.LatLng(51.0360272, 3.7359072),
                zoom: 8
            };
            map = new google.maps.Map(document.getElementById("map-canvas"),
                mapOptions);

            _.each(profileMarkers, function(profile) {
                new google.maps.Marker({
                    position: new google.maps.LatLng(profile.geo[1], profile.geo[0]),
                    map: map,
                    title: profile.name
                });
            });
        }

        google.maps.event.addDomListener(window, 'load', initialise);

block content
   .container
        div(id="map-canvas", style="width:100%; height:700px;")
于 2014-03-08T15:20:56.603 に答える
0

「未定義のプロパティ 'maps' を読み取れません」

これはどうしようもありません。Google マップの初期化に失敗したか、そのようなことのようです。

しかし、Jade テンプレートで JavaScript を実行したい場合は、行をダッシュ​​で始めるだけでよいと言えます。var x = Math.random()

で始まる行に(別の)エラーがあると思います#{new google.maps.Maker...
これは JS ではなく、Jade であり、その結果、コンストラクターが HTML タグとして使用されます。それは望ましくないと思います。

以下に例を示します。http://jade-lang.com/demo/のオンライン エディタに貼り付けることができます。

- var ar = [1,2,3]
ul
  each item in ar
    - var x = Math.random()*item
    li= x

Jade 構文のヒントについては、私の要点を確認してください。

于 2014-03-07T22:26:55.677 に答える