У меня есть форма, которую я хочу отправить с помощью ajax-post на свой контроллер. Тем временем HTML ожидает генерации и сохранения записей, я хочу отобразить прогресс (пока только числа). Я действительно не понимаю, почему следующий код не обновляет <div id="progress"> на Session::get('progress').

Контроллер:

public function postGenerate() {
    // getting values from form (like $record_num)
    Session::flash('progress', 0);
    $i = 1;
    for ($i; $i < $record_num; $i++) {
        $record = new Record();
        // adding attributes...
        $record->save;
        Session::flash('progress', $i);
    }
    $response = Response::make();
    $response->header('Content-Type', 'application/json');
    return $response;
}

Javascript:

@section('scripts')
<script type="text/javascript">
    $(document).ready(function() {
        $('#form-overview').on('submit', function() {
            setInterval(function(){
                $('#progress').html( "{{ Session::get('progress') }}" );
            }, 1000);
            $.post(
                $(this).prop('action'),
                {"_token": $(this).find('input[name=_token]').val()},
                function() {
                    window.location.href = 'success';
                },
                'json'
            );
            return false;
        });
    });
</script>   
@stop

HTML:

@section('content')
    {{ Form::open(array('url' => 'code/generate', 'class' => 'form-inline', 'role' => 'form', 'id' => 'form-overview' )) }}
    <!-- different inputs ... -->
        {{ Form::submit('Codes generieren', array('class' => 'btn btn-lg btn-success')) }}
    {{ Form::close() }}

    <div id="progress">-1</div>
@stop
5
carl 3 Фев 2014 в 19:08
Скорее всего, данные сеанса не сохранятся до конца запроса.
 – 
ceejayoz
3 Фев 2014 в 21:02
Мне кажется, что сеанс вообще не обновляется - даже после завершения запроса он все еще содержит начальное значение. Кто-нибудь может объяснить такое поведение ??
 – 
carl
3 Фев 2014 в 21:20
1
Это потому, что {{ Session::get('progess') }} оценивается только один раз, когда страница сначала отображается.
 – 
rmobis
3 Фев 2014 в 21:20

1 ответ

Лучший ответ

Это потому, что {{ Session::get('progess') }} оценивается только один раз, когда страница сначала отображается. Единственный способ сделать то, что вы хотите, - это фактически сделать дополнительные запросы AJAX к другому URL-адресу, который сообщает о ходе выполнения. Что-то вроде этого:

Контроллер

// Mapped to yoursite.com/progress
public function getProgess() {
    return Response::json(array(Session::get('progress')));
}

public function postGenerate() {
    // getting values from form (like $record_num)
    Session::put('progress', 0);
    Session::save(); // Remember to call save()

    for ($i = 1; $i < $record_num; $i++) {
        $record = new Record();

        // adding attributes...

        $record->save();
        Session::put('progress', $i);
        Session::save(); // Remember to call save()
    }

    $response = Response::make();
    $response->header('Content-Type', 'application/json');
    return $response;
}

JavaScript

@section('scripts')
<script type="text/javascript">
    $(document).ready(function() {
        $('#form-overview').on('submit', function() {
            setInterval(function(){
                $.getJSON('/progress', function(data) {
                    $('#progress').html(data[0]);
                });
            }, 1000);

            $.post(
                $(this).prop('action'),
                {"_token": $(this).find('input[name=_token]').val()},
                function() {
                    window.location.href = 'success';
                },
                'json'
            );

            return false;
        });
    });
</script>   
@stop
6
rmobis 3 Фев 2014 в 21:38
Raphael_, большое спасибо! Хотя предложенное вами решение, кажется, указывает правильное направление, я не смог решить свою проблему к настоящему времени: getJSON('/progress'... срабатывает непрерывно, это хорошо. Но их ответы приходят не раньше, чем поступит ответ от $.post. Итак, <div> обновляется с опозданием !
 – 
carl
4 Фев 2014 в 12:40
Вероятно, это потому, что ваше основное действие слишком быстрое. (Как это кажется, поскольку все, что вы делаете, это сохраняете несколько записей в базе данных)
 – 
rmobis
4 Фев 2014 в 21:27
Нет, мое основное действие определенно занимает довольно много времени. Но после еще нескольких исследований я обнаружил, что проблема вызвана заблокированными данными сеанса. Я могу решить эту проблему с помощью простого session_write_close. Более подробную информацию можно найти здесь: stackoverflow.com / questions / 6903318 /…
 – 
carl
5 Фев 2014 в 16:08
1
Понятно ... Я думал, что Session::save() должен был это сделать.
 – 
rmobis
5 Фев 2014 в 23:08
Спасибо за идею. За исключением того, что вместо сеанса я использую временную таблицу MySQL.
 – 
Daniel
10 Янв 2015 в 01:00