我正在构建一个Web应用程序,其中有许多可单击的地图,它们存储为静态SVG文件,希望能够基于菜单单击而动态交换。到目前为止,我有JavaScript代码来调用Catalyst控制器,并且希望它在响应正文中返回SVG文件的内容。到目前为止,我可以获取JavaScript来捕捉菜单单击并调用控制器,在控制器中,我可以从数据库中获取文件的名称。不过,我仍然停留在该步骤上,到目前为止,还无法找到如何在控制器中读取该文件的内容并将其返回给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>


佩尔

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中的load函数中,传入一个为您返回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函数应仅将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");
}


这将使您的应用程序脱离文档处理业务,精简控制器,并允许您的Web服务器执行其最擅长的工作-提供文档。

10-05 20:45
查看更多