Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 05.08.2013, 02:06
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

забыл angular.isArrayLikeObject:
(function() {

    'use strict';


    angular.extend( angular, {
        isArrayLikeObject: isArrayLikeObject
    });


    /**
     * Проверяет, является ли переданное значение массивоподобным объектом
     * @param item {*}
     * @returns {boolean}
     */
    function isArrayLikeObject( item ) {
        if ( angular.isObject( item ) ) {
            return 'length' in item;
        } else {
            return false;
        }
    }


}());
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #12 (permalink)  
Старый 05.08.2013, 17:19
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

Клево! Тоже написал директиву для загрузки, которая работает с ресурсами. Одна проблема, которую пока не смог победить — отмена загрузки. Т.е. при удалении элемента, связанного с загружаемым файлом должна отменяться загрузка (функцией abort). К сожалению, отдельно эту функцию из xhr не перетащить в scope (не будет работать), а при копировании всего объекта xhr в scope постоянно появляются ошибки.

Как разберусь — тоже выложу)
Ответить с цитированием
  #13 (permalink)  
Старый 06.08.2013, 01:41
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Если интересно, переписал код (но еще не закончил) http://learn.javascript.ru/play/7VhTcc

упразднил все сервисы, кроме $fileUploader

p.s.: работает из песочницы (без сервера)
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 06.08.2013 в 01:44.
Ответить с цитированием
  #14 (permalink)  
Старый 06.08.2013, 20:38
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

У меня всё проще. Существует всего одна директива ui-file, которая накладывается на любой тег, после чего на область в теге становится сразу возможным перетаскивать файлы. Если этим тегом является инпут с типом file, то загружать можно еще и стандартным способом. В будущем можно сделать, чтобы такой невидимый инпут генерировался бы автоматически, если директива будет применена к ссылке или кнопке.

Директива: http://plnkr.co/edit/5Ke7tELWHkSgoCU7IpHm?p=preview
Пример надо еще допиливать

Стараюсь делать как можно меньше общих функций между директивой и областью видимости. По сути, должна быть только одна createItem, а прогресс, имя файла и т.п. уже в модель записывать.

Последний раз редактировалось Shitbox2, 06.08.2013 в 20:59.
Ответить с цитированием
  #15 (permalink)  
Старый 06.08.2013, 22:01
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от Shitbox2
У меня всё проще
ну, я бы не сказал, что у меня сложно сколько людей столько и мнений сколько проггеров, столько и реализаций )

Мои вопросы и комментарии:
1. Для чего эта проверка?
var ok = e.dataTransfer && e.dataTransfer.types && e.dataTransfer.types.indexOf('Files') >= 0


в моей реализации есть такая штука
var dataTransfer = event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; // jQuery fix;

фиксит подключении жуквери (т.е., если подключаешь жуквери, то получаешь ошибку без этого фикса)

в моей реализации
.directive( 'ngFileDrop', function( $fileUploader ) {
    return {
        // don't use drag-n-drop files in IE9, because not File API support
        link: !window.File ? angular.noop : function( $scope, $element ) {
            // code
        }
    };
})

обрати внимание на строку линковки. В IE9 есть событие сброса, но нету файлов Будь осторожен )

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

В моей реализации можно:
- загружать файлы с дран-н-дропом и с помощью инпута
- либо только дран-н-дропом
- либо только инпутом
В моей реализации ловящих областей может быть много, также как и инпутов.

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

4. валидаторы и генерацию превьюшек я бы вынес из директивы... и я вынес

5. благодаря паттерну "наблюдатель" в моей реализации, за событиями загрузки и добавления в очередь могут следить сразу несколько контроллеров
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 06.08.2013 в 22:13.
Ответить с цитированием
  #16 (permalink)  
Старый 07.08.2013, 10:39
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

Цитата:
var ok = e.dataTransfer && e.dataTransfer.types && e.dataTransfer.types.indexOf('Files') >= 0
1. Эту штуку бездумно скопировал с какого-то примера и пока еще не разбирался нужна ли она в таком виде)) Твою штуку возьму на заметку

P.S. У меня с jQuery не глючит, кстати.

Цитата:
Если она висит на инпуте, то и сброс файла необходимо производить в инпут (что удобно далеко не всегда, проще бросать на документ, например)
2. Тут просто нужно использовать директиву два раза. Один раз на инпут, второй раз на область перетаскивания (можно хоть 100 областей перетаскивания и инпутов сделать) — в одной области видимости все директивы загрузки будут работать с одной функцией createItem и загружать всё в одно место.

Цитата:
Не понял, можно ли в твоей реализации "загружать по кнопке", т.е. сбросили файлы, а затем нажали кнопку загрузить (у меня для этого есть очередь)
3. Нельзя) В самом конце сделаю, если будет просто. Размышляя над философией загрузки пришел к выводу, что файлы нужно всегда грузить сразу (и показывать пользователю в обработанном виде). Так же файлы нужно всегда грузить в отдельном потоке на файл. Во-первых, ограничение сервера (10 Мб, например) не будет делиться на все файлы, во-вторых, можно каждому файлу задать отдельный прелоадер.

Цитата:
валидаторы и генерацию превьюшек я бы вынес из директивы... и я вынес
4. А я, напротив, внес)) Очень бесит, когда ставишь плагин загрузки и приходится его допиливать или дособирать, чтобы он превьюшки читал. Простейшая валидация, кстати, входит в стандартные директивы формы ;-) У меня тоже она есть. При желании можно на свою заменить, но в 99,9% не потребуется.

Цитата:
благодаря паттерну "наблюдатель" в моей реализации, за событиями загрузки и добавления в очередь могут следить сразу несколько контроллеров
5. Это не для средних умов))) Тоже ковырял в этом направлении, но пока отказался. В моем варианте события отражаются в модели, а ее может мониторить кто угодно)

Пока основной кейс, в котором тестирую, такой: http://tamtakoe.ru/photoalbum/. Включает в себя практически все ситуации (кроме общего прогресса). Еще хочу уйти от функций в области видимости и вынести createItem() в настройку директивы...

Последний раз редактировалось Shitbox2, 07.08.2013 в 14:03.
Ответить с цитированием
  #17 (permalink)  
Старый 07.08.2013, 20:48
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

В первом приближении... Вот демка http://tamtakoe.ru/uploader/

А тут демка, где можно с фронтендом пограть (в последних браузерах): http://plnkr.co/edit/HKbvgle4zqfqCKcpLJDi?p=preview. Ключевой файл file.js

Апи примерно устаканилось. Осталось сделать отмену загрузки и подтягивать кроссбраузерность
Ответить с цитированием
  #18 (permalink)  
Старый 09.08.2013, 01:18
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Shitbox2, молодец ) Ковер и гендольф (или как его там) заслуживают отдельного упоминания

у меня пока такая штука получилась http://www.screencapture.ru/file/1190575A

Что есть:
Директивы:
- ngFileSelect - вешается на <input type="file" />
- ngFileDrop - вешается на DOM элемент, кот. будет ловить файлы (как правило, это весь документ)
- ngFileOver - вешается на элемент, кот. будет реагировать (добавляться класс), когда файлы находятся над drop элементом. По умолчанию добавляется класс "ng-file-over". Другой класс можно задать в параметре атрибута ng-file-over="className"
(в этом плане ничего не менял)

Один сервис:
- $fileUploader - управление очередью и загрузка файлов

$fileUploader
свойства:
- url: общий для всех файлов. Можно индивидуализировать для каждого файла, после добавления файла в хранилище
- alias - псевдоним, под которым сервер увидит файл. Общий для всех файлов. Можно индивидуализировать для каждого файла, после добавления файла в хранилище
- autoUpload - автозагрузка (true/false)
- removeAfterUpload - удалить из очереди после загрузки (true/false)
- filters - фильтры, применяемые к файлам перед добавлением в очередь. По умолчанию присутствует simple filer : )
- queue - очередь
методы:
- bind - пожалуй, один из наиболее важных. Регистрирует коллбеки. Позволяет повесить на одно событие сколько угодно (в пределах разумного ) обработчиков.
- addToQueue - добавляет файлы в очередь загрузки
- removeFromQueue - удаляет файл из очереди по индексу
- clearQueue - очищает очередь
- uploadItem - загружает файл по индексу
- uploadAll - загружает все файлы в очереди
коллбеки:
- afteraddingfile - после добавления файла в очередь
- afteraddingall - после добавления всех файлов в очередь
- beforeupload - перед загрузкой
- progress - индикация загрузки файла
- success - успешная загрузка
- error - ошибка при загрузке
- complete - загрузка завершена

Чтобы было проще понять, приведу кусок кода:
app.controller( 'MainController', function( $scope, $fileUploader ) {
    $scope.model = {};

    // пользовательские фильтры
    $scope.filter1 = function( item ) {
        console.log( 'filter1' );
        return true;
    };

    // их может быть много, главное их добавить (push)
    $scope.filter2 = function( item ) {
        console.log( 'filter2' );
        return true;
    };

    // коллбек "после добавления файла в очередь"
    $scope.afterAddingFile = function( item ) {
        console.log( item );
    };

    // коллбек "после добавления всех файлов в очередь"
    $scope.afterAddingAll = function( items ) {
        $scope.model.items = $fileUploader.queue;
        $scope.$apply();
    };

    // коллбек "перед загрузкой"
    $scope.beforeUpload = function( item ) {
        console.log( item );
    };

    // коллбек "progress для файла"
    $scope.progress = function( progress ) {
        console.log( 'Progress: ' + progress );
        $scope.$apply();
    };

    // коллбек "success для файла"
    $scope.success = function( xhr ) {
        console.log( 'Success: ' + xhr.response );
    };

    // коллбек "complete для файла"
    $scope.complete = function( xhr ) {
        console.log( 'Complete: ' + xhr.response );
        $scope.$apply();
    };

    // управление очередью
    $scope.uploadAll = function() {
        $fileUploader.uploadAll();
    };

    // управление очередью
    $scope.removeAll = function() {
        $fileUploader.clearQueue();
    };

    $fileUploader.url = '/upload.php';

    // добавление фильтров
    $fileUploader.filters.push( $scope.filter1 );
    $fileUploader.filters.push( $scope.filter2 );

    // регистрация наблюдателей
    $fileUploader.bind( 'afteraddingfile', $scope.afterAddingFile );
    $fileUploader.bind( 'afteraddingall', $scope.afterAddingAll );
    $fileUploader.bind( 'beforeupload', $scope.beforeUpload );
    $fileUploader.bind( 'progress', $scope.progress );
    $fileUploader.bind( 'success', $scope.success );
    $fileUploader.bind( 'complete', $scope.complete );
});

т.о. на любое событие может подписаться произвольное количество раз любой контроллер (или несколько контроллеров)
код http://learn.javascript.ru/play/DUtgpc

Насчет абортов. Говорят, это плохо

Хочу сделать Progress, Success(may be) и Complete для всей очереди, после чего приступлю к генерации превьюшек. Скорее всего у меня будет для этого отдельный сервис.

Как то так
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 09.08.2013 в 01:35.
Ответить с цитированием
  #19 (permalink)  
Старый 12.08.2013, 16:32
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

https://github.com/nervgh/angular-file-upload
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #20 (permalink)  
Старый 12.08.2013, 17:30
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

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



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
drag & drop, mouseup cyber Events/DOM/Window 108 01.07.2012 23:31
drag & drop , html 5 cyber Events/DOM/Window 1 30.06.2012 14:16
Дебаг js, или как найти обработчик события для тега jimm88 Events/DOM/Window 1 18.04.2012 14:11
Отмена drag and drop браузера l-liava-l Элементы интерфейса 0 02.04.2012 12:53
Как отлаживать события? Или как сделать трассировку вызовов функций? gennad Events/DOM/Window 1 18.08.2010 12:21