我试图在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;")
地图显示正确,但当我添加&#39;每个&#39;代码块我收到错误&#34;无法读取属性&#39; maps&#39;未定义&#34;。
如何添加一条在&#39;每个&#39;上执行的js代码?在玉?
答案 0 :(得分:6)
你真的很接近,唯一的问题是变量的内部,即#{this_stuff}
是所有在玉的上下文中执行(不会有{{1} } object,因为这是客户端的。)
这有点棘手,因为您在这里处理两个完全不同的JavaScript环境:服务器端和客户端。
因此,您需要将jade中的服务器端变量输出到将在客户端执行的javascript代码中。
在相关的说明中,可以在脚本块中使用Jade变量语法,但不能执行其他操作(如循环)。
首先,让我们清理它,以便所有google
标记位于script
块中(假设您使用的示例KeystoneJS模板位于js
的底部})并正确生成这些配置文件:
<body>
这种情况越来越接近了(Jade会产生你现在所期望的),但是它还不会起作用,因为你可能会在之前将标记添加到地图 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;")
函数已运行。
它也没有转义值,因此名称中的initialize
字符之类的内容会导致语法错误。
更强大的方法是填充客户端数组,然后在创建地图后循环遍历。我们还会使用"
来确保正确转义值。
JSON.stringify
请注意对!{variable}的更改,以便JSON不会转义
最后,我建议在路径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;")
文件中为视图构建profiles
数组,而不是在jade模板中进行。它更干净,您的页面中不会有大量.js
个标签。
所以你的路线看起来像这样(我假设有一点点给你这个想法,并使用underscore使代码比vanilla javascript更整洁)
<script>
然后在您的视图模板中:
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');
}
答案 1 :(得分:0)
“无法读取未定义的属性'地图'”
无法解决这个问题,似乎谷歌地图无法初始化或类似的事情。
但我可以告诉你,如果你想在你的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语法提示:https://gist.github.com/timaschew/7543cf3d0c455f686784