Javascript-форум (https://javascript.ru/forum/)
-   Angular.js (https://javascript.ru/forum/angular/)
-   -   Глобальные события или drag & drop (https://javascript.ru/forum/angular/39887-globalnye-sobytiya-ili-drag-drop.html)

nerv_ 12.08.2013 19:29

Цитата:

Сообщение от Shitbox2
А нужен ли observer? Я делаю проще. Подключаю $rootScope где надо и просто подписываюсь $rootScope.$on('myAction', fn). В любом случае все события до корневой области дойдут)

правильное замечание, спасибо :) Скорее всего перепишу код - уберу observer.

Он еще внутри используется: аккумулирует события и перераспределяет их (aka proxy). Скорее всего создам для этого изолированный scope, чтобы с ним можно было работать подобным образом (on, off, fire).

Еще было бы неплохо внедрение в scope контроллера сделать, чтобы обертки не писать.

nerv_ 12.08.2013 23:59

Переписал и сделал немного удобней :D

https://github.com/nervgh/angular-fi...controllers.js

Shitbox2 14.08.2013 10:03

Странное вынесение колбэков. Почему не сделать так?
var uploader = $fileUploader.create({
    url: '/upload.php',
    filters: [
        function( item ) {                    // first user filter
            console.log( 'filter1' );
            return true;
        }
    ],
    //Колбэки
    afteraddingfile: function () { ... },
    afteraddingall: function () { ... },
    ...
});

Распространенная практика упаковывать колбэки в объект настроек, чтобы всё было в одном месте. Вынесение АПИ в отдельный объект применяется, как правило, для методов, т. к. методы как раз приходится вызывать из разных мест, напр.: uploader.send()

nerv_ 14.08.2013 13:40

Цитата:

Сообщение от Shitbox2
Странное вынесение колбэков

это не коллбеки, это события :) Т.е. на одно событие можно подписаться много раз:

// create a uploader with options
var uploader = $fileUploader.create({
    url: '/upload.php',
    filters: [
        function( item ) {                    // first user filter
            console.log( 'filter1' );
            return true;
        }
    ]
});

// REGISTER HANDLERS

uploader.bind( 'afteraddingfile', function( event, item ) {
    console.log( 'After adding a file 1', item );
});

uploader.bind( 'afteraddingfile', function( event, item ) {
    console.log( 'After adding a file 2', item );
});

Shitbox2 14.08.2013 20:31

А зачем?)

P.S.
И еще не очень с очередью понятно. К примеру, у меня, как помнишь, так:
create: function (file, uploadFile) {
    //Создаем пустой элемент для будущего файла
    $scope.add('after', function (index, fileEl, permit) {

    angular.extend(fileEl, file) //Записываем айдишник элемента в объект файла
                
    uploadFile($scope.url + '/' + fileEl.id, fileEl, permit) //Загружаем файл
})

Т.е. fileEl (надо будет переименовать в queue :) содержит информацию об выбранных файлах. Это массив и его можно менять как угодно стандартными методами. Зачем делать очередь с отдельными методами добавления, доступа?

nerv_ 15.08.2013 00:57

Цитата:

Сообщение от Shitbox2
А зачем?)

потому, что это удобно :) По твоему, зачем в DOM есть метод addEventListener?

Цитата:

Сообщение от Shitbox2
Зачем делать очередь с отдельными методами добавления, доступа?

все просто: моя очередь не приватная - это свойство загрузчика, которое является массивом. С одной стороны это не безопасно, с другой, позволяет внедрить ее в аргуляр без проблем:
$scope.uploader = uploader;

где шаблон
<ul>
    <li ng-repeat="item in uploader.queue">
</ul>

подробнее в разметке
Методов доступа к ней не писал (предполагается использование стандартных способов работы с массивами). Есть метод добавления в очередь, удаления из нее (методы загрузчика).

Метод addToQueue нужен потому, что:
- перед добавлением в очередь, каждый элемент проходит фильтры (что позволяет валидировать очередь) ссылка
- после добавления элемента[file|input] в очередь, он становится элементом очереди (приобретает свое api), что позволяет писать разметку вида
<ul>
    <li ng-repeat="item in uploader.queue">
        <div>Name: {{ item.file.name }}</div>
        <div>Size: {{ item.file.size }}</div>
        <div>
            Progress: {{ item.progress }}
            <div class="item-progress-box">
                <div class="item-progress" ng-style="{ 'width': item.progress + '%' }"></div>
            </div>
        </div>
        <div>Uploaded: {{ item.isUploaded }}</div>
        <div>
            <a ng-href="#" ng-click="item.upload()" ng-hide="item.isUploaded" >upload</a>
            <a ng-href="#" ng-click="item.remove()">delete</a>
        </div>
    </li>
</ul>

- вызываются события "afteraddingfile", "afteraddingall", "changedqueue". На примере события "afteraddingfile" покажу процесс кастомизации:
uploader.bind( 'afteraddingfile', function( event, item ) {
    // здесь, например, можно менять свойства элемента очереди, такие как alias, url, headers ... etc
   // можно дать команду на немедленную загрузку - item.upload()
   // или удалить item.remove() и т.п.
});

- на этапе добавления в очередь убираются браузерные различия (xh2 & iframe):
item.upload();
uploader.uploadItem( [index|item] );
uploader.uploadAll( [index|item] );

- почему надо делать удаление через методы загрузчика - iframe transport (остаются скрытые инпуты, формы и фреймы)

возможно, сделаю очередь защищенным свойством и добавлю пару методов для феншуя, но особых проблем не вижу, если руки прямые :)

Shitbox2 21.08.2013 17:51

А ты тестировал iframe? Пытаюсь так же добавить поддержку, твой код не работает. В Хроме выдает ответ в модальном окне (с адресом запроса) с ошибкой UPLOAD_ERR_NO_FILE ПХП загрузчика. В IE просто не работает)

nerv_ 21.08.2013 18:43

Цитата:

Сообщение от Shitbox2
А ты тестировал iframe?

да

Цитата:

Сообщение от Shitbox2
твой код не работает

не верю, давай песочницу, где мой код не работает.

чтобы протестировать мой код с фреймовым загрузчиком, достаточно сделать это (разумеется выбирать через инпут)

// It is attached to <input type="file" /> element
.directive( 'ngFileSelect', function() {
    return {
        link: function( $scope, $element ) {
            if ( !window.File || !window.FormData ) {
                $element.removeAttr( 'multiple' );
            }

            $element.bind( 'change', function() {
                $scope.$emit( 'file:add', this );
//                    $scope.$emit( 'file:add', this.files ? this.files : this );
            });
        }
    }
});

Shitbox2 21.08.2013 19:32

Я тестировал так: http://learn.javascript.ru/play/GLyoJ
Изменения с 255 строки в files.js

nerv_ 21.08.2013 20:44

Цитата:

Сообщение от Shitbox2
Я тестировал так

привет от политики безопасности - нельзя создать инпут type="file" c полем value, и присвоить ему значениеhttp://learn.javascript.ru/play/UyWPy


Часовой пояс GMT +3, время: 09:07.