Показать сообщение отдельно
  #74 (permalink)  
Старый 26.12.2011, 20:57
Аватар для x-yuri
Отправить личное сообщение для x-yuri Посмотреть профиль Найти все сообщения от x-yuri
 
Регистрация: 27.12.2008
Сообщений: 4,201

давайте все же расмотрим конкретный пример: ресайз картинок на клиенте с помощью flash.

Например, есть форма изменения юзерпика, в которой пользователь выбирает изображение. В результате появляется диалоговое окно, в котором пользователь указывает, как надо обрезать это изображение. Нажимает "Ok" диалогового окна, потом кнопку "Сохранить" формы. Получается что-то типа:
var chain = new AsyncChain();
$('jsChangeUserpicForm-eUserpicField').addEvent('change',   // input type="file"
    chain
        .setOptions({
            onFailure: function() {
                // показать пользователю сообщение об ошибке
                this.fireEvent('complete');
            },
            onComplete: function() {
                new Button('jsChangeUserpicForm-eAttachFileLink')
                    .enable();
                $('jsChangeUserpicForm-eAttachFileThrobber')
                    .addClass('sInvisible');
                this.state('cropResizeUserpicDialog')
                    && this.state('cropResizeUserpicDialog').close();
            }
        })
        .add(function() {
            new Button('jsChangeUserpicForm-eAttachFileLink')
                .disable();
            $('jsChangeUserpicForm-eAttachFileThrobber')
                .removeClass('sInvisible');
        })
        .add(function(NEXT) {
            sendForm({
                form: 'jsChangeUserpicForm',
                url: '/upload/userpic',
                onSuccess: function(userpicURL) {
                    chain.state('userpicURL', userpicURL);
                    NEXT();
                },
                onFailure: function() {
                    chain.fireEvent('failure');
                }
            });
        })
        .add(function(NEXT) {
            this.state('cropResizeUserpicDialog', new CropResizeUserpicDialog({
                userpicURL: chain.state('userpicURL'),
                dstWidth: 100,
                dstHeight: 100,
                onOk: function(cropX, cropY, cropWidth, cropHeight, resizeWidth, 

resizeHeight) {
                    this.state({
                        cropX: cropX,
                        cropY: cropY,
                        cropWidth: cropWidth,
                        cropHeight: cropHeight,
                        resizeWidth: resizeWidth,
                        resizeHeight: resizeHeight
                    });
                    NEXT();
                },
                onCancel: function() {
                    chain.fireEvent('complete');
                }
            }));
        })
        .add(function() {
            this.state('cropResize', new CropResize());
            this.state('cropResize').load(this.state('userpicURL'), {
                onSuccess: function() {
                    NEXT();
                },
                onFailure: function() {
                    chain.fireEvent('failure');
                }
            });
        })
        .add(function() {
            this.state('cropResize')
                .crop(
                    this.state('cropX'),
                    this.state('cropY'),
                    this.state('cropWidth'),
                    this.state('cropHeight')
                )
                .resize(
                    this.state('resizeWidth'), this.state('resizeHeight'),
                )
                .save({
                    url: '/upload/thumb',
                    onSuccess: function() {
                        NEXT();
                    },
                    onFailure: function() {
                        chain.fireEvent('failure');
                    }
                });
        })
        .add(function() {
            if ($('jsChangeUserpicForm-eUserpicURLField')) {
                var eUserpicURLField = $('jsChangeUserpicForm-eUserpicURLField');
            } else {
                var eUserpicURLField = new Element({
                    id: 'jsChangeUserpicForm-eUserpicField',
                    type: 'hidden'
                });
                eUserpicURLField.inject('jsChangeUserpicForm');
            }
            eUserpicURLField.name = 'userpic-url';
            eUserpicURLField.value = this.state('userpicURL');

            $('jsChangeUserpicForm-eUserpicThumb').src = this.state('userpicURL');
        });
);

дополнительные преимущества:
1) возможность научить addEvent запускать цепочки в ответ на событие;
2) предоставление интерфейса для работы с состоянием позволяет повторно использовать цепочку - для этого надо перед запуском цепочки очистить состояние; если пользователь сам придумывает, где хранить состояние, нету возможности его очистить;
3) возможность организовать аналогию блока finally из try-catch (событие complete).

p.s. это я называю конкретным примером. Наличие кода необязательно в общем-то, но в твоем примере с гипотетическим парсером непонятно даже какие действия составляют цепочку, не говоря уже о данных, составляющих состояние цепочки. Т.е. не хватает важной информации.

Последний раз редактировалось x-yuri, 26.12.2011 в 21:03.
Ответить с цитированием