Используйте катализатор и Ajax, чтобы обновить блок SVG

Я создаю веб-приложение, в котором у меня есть несколько интерактивных карт, хранящихся в виде статических файлов 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>

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/

1 ответ

Решение

Если у вас нет причин для этого, я бы использовал ваш веб-сервер (Apache, nginx, ...) для обслуживания файла вместо того, чтобы обрабатывать файловый ввод / вывод внутри вашего контроллера.

В вашей функции загрузки в javascript передайте функцию, которая возвращает URL для вас:

$(document.getElementById("som_map")).load(getSVGUrl(this.title));

Затем определите эту функцию для вызова Catalyst, чтобы получить соответствующий URL для данного mapId:

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");
}

Это выведет ваше приложение из сферы обработки документов, урезает ваш контроллер и позволит вашему веб-серверу делать то, что он делает лучше всего - обслуживать документы.

Другие вопросы по тегам