使用催化剂和 Ajax 刷新 SVG 块
Use catalyst and Ajax to refresh an SVG block
我正在构建一个网络应用程序,其中我有许多可点击的地图,存储为静态 SVG 文件,我希望能够根据菜单点击动态交换。到目前为止,我有 javascript 代码来调用我的 Catalyst 控制器,我希望它 return 响应主体中的 SVG 文件的内容。到目前为止,我可以获得 javascript 来捕捉菜单点击并调用控制器,并且在控制器中我能够从我的数据库中获取文件的名称。不过,我卡在了那一步,到目前为止,我一直无法找到如何在控制器中读取该文件的内容并将其 return 发送到 javascript 控制器。如有任何帮助,我们将不胜感激!
更新:
下面的(已编辑)代码有效,但我不确定这是否是最佳方法。我绝对乐于接受有关改进流程的建议。谢谢!
Javascript:
$(document).on("click",".map_select", function(e){
$(document.getElementById("som_map")).load("[% c.uri_for('/maps/update_map/') %]" + this.title);
})
HTML
<svg id="som_map" class="mapmain" width="720px" height="430px">
</svg>
PERL
sub update_map :Path :Local :Args(1) {
my ( $self, $c, $map_id ) = @_;
my $fields = $c->model('DB::Map')->find($map_id);
my $map_file = $fields->get_column('map_file');
my $svg;
my $path = "root/static/svg/$map_file";
open my $fh, '<', $path;
{
local $/ = undef;
$svg = <$fh>;
}
close $fh;
$c->res->body($svg);
}
SVG 文件存储在 root/static/svg/
除非您有理由这样做,否则我会使用您的 Web 服务器(Apache、nginx 等)为您提供文件,而不是在您的控制器中处理文件 I/O。
在 javascript 中的加载函数中,传入一个 return 为您 URL 的函数:
$(document.getElementById("som_map")).load(getSVGUrl(this.title));
然后定义该函数以调用 Catalyst 以获得给定 mapId 的适当 URL:
function getUrl(mapId) {
var returnUrl;
jQuery.ajax({
url: "[% c.uri_for('/maps/update_map/') %]"
+ mapId,
success: function(result) {
if(result.isOk == false)
returnUrl = result.message;
},
async: false,
dataType: 'text/plain'
});
return returnUrl;
}
此函数应调用您的应用程序,并期望返回 URL。它应该足够快,使其同步并不重要。
最后,您的 Catalyst 函数应该 return URL 到文档:
sub update_map :Path :Local :Args(1) {
my ( $self, $c, $map_id ) = @_;
my $fields = $c->model('DB::Map')->find($map_id);
my $map_file = $fields->get_column('map_file');
$c->res->body("<appropriate URL path to document>/$map_file");
}
这将使您的应用程序脱离文档处理业务,trim 关闭您的控制器,并允许您的网络服务器做它最擅长的事情——服务文档。
我正在构建一个网络应用程序,其中我有许多可点击的地图,存储为静态 SVG 文件,我希望能够根据菜单点击动态交换。到目前为止,我有 javascript 代码来调用我的 Catalyst 控制器,我希望它 return 响应主体中的 SVG 文件的内容。到目前为止,我可以获得 javascript 来捕捉菜单点击并调用控制器,并且在控制器中我能够从我的数据库中获取文件的名称。不过,我卡在了那一步,到目前为止,我一直无法找到如何在控制器中读取该文件的内容并将其 return 发送到 javascript 控制器。如有任何帮助,我们将不胜感激!
更新:
下面的(已编辑)代码有效,但我不确定这是否是最佳方法。我绝对乐于接受有关改进流程的建议。谢谢!
Javascript:
$(document).on("click",".map_select", function(e){
$(document.getElementById("som_map")).load("[% c.uri_for('/maps/update_map/') %]" + this.title);
})
HTML
<svg id="som_map" class="mapmain" width="720px" height="430px">
</svg>
PERL
sub update_map :Path :Local :Args(1) {
my ( $self, $c, $map_id ) = @_;
my $fields = $c->model('DB::Map')->find($map_id);
my $map_file = $fields->get_column('map_file');
my $svg;
my $path = "root/static/svg/$map_file";
open my $fh, '<', $path;
{
local $/ = undef;
$svg = <$fh>;
}
close $fh;
$c->res->body($svg);
}
SVG 文件存储在 root/static/svg/
除非您有理由这样做,否则我会使用您的 Web 服务器(Apache、nginx 等)为您提供文件,而不是在您的控制器中处理文件 I/O。
在 javascript 中的加载函数中,传入一个 return 为您 URL 的函数:
$(document.getElementById("som_map")).load(getSVGUrl(this.title));
然后定义该函数以调用 Catalyst 以获得给定 mapId 的适当 URL:
function getUrl(mapId) {
var returnUrl;
jQuery.ajax({
url: "[% c.uri_for('/maps/update_map/') %]"
+ mapId,
success: function(result) {
if(result.isOk == false)
returnUrl = result.message;
},
async: false,
dataType: 'text/plain'
});
return returnUrl;
}
此函数应调用您的应用程序,并期望返回 URL。它应该足够快,使其同步并不重要。
最后,您的 Catalyst 函数应该 return URL 到文档:
sub update_map :Path :Local :Args(1) {
my ( $self, $c, $map_id ) = @_;
my $fields = $c->model('DB::Map')->find($map_id);
my $map_file = $fields->get_column('map_file');
$c->res->body("<appropriate URL path to document>/$map_file");
}
这将使您的应用程序脱离文档处理业务,trim 关闭您的控制器,并允许您的网络服务器做它最擅长的事情——服务文档。