我正在尝试在 Jade 模板中实现 Google map 。使用 KeystoneJS 作为 CMS,我有许多“个人资料”(基本上是有地址的人),我想将其作为标记添加到 map 中。
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;")
map 显示正确,但当我添加“每个”代码块时,出现错误“无法读取未定义的属性‘ map ’”。
如何在 Jade 中添加一段在“每个”上执行的 js 代码?
最佳答案
你真的很接近,唯一的问题是变量的内部,即 #{this_stuff}
所有 都是在 jade 的上下文中执行的(不会有 google
对象,因为这是客户端)。
这有点棘手,因为您在这里处理两个完全不同的 javascript 环境:服务器端和客户端。
所以你需要在你的 jade 中输出服务器端的变量,到客户端执行的 javascript 代码中。
在相关说明中,您可以在脚本 block 中使用 Jade 变量语法,但不能做其他事情(如循环)。
首先,让我们清理一下所有的 script
标签在 js
中 block (假设您使用的示例 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 将生成您现在所期望的),但它(目前)还行不通,因为您可能会在之前将标记添加到 map initialize
函数已运行。
它也没有转义值,所以像 "
这样的东西名称中的字符会导致语法错误。
一种更稳健的方法是填充客户端数组,然后在创建 map 后循环遍历该数组。我们还将使用 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;")
请注意对 !{variable} 的更改,这样 JSON 就不会被转义
最后,我建议构建 profiles
route 的数组 .js
View 文件,而不是在 jade 模板中执行。它更干净,你不会得到一堆 <script>
页面中的标记。
所以你的路线看起来像这样(我假设有点给你这个想法,并使用 underscore 使代码比 vanilla 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');
}
然后在你的 View 模板中:
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;")
关于javascript - 在 Jade 中调用每个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22252520/