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)

Shitbox2 15.07.2013 22:06

Глобальные события или drag & drop
 
Нужно сделать поле для перетаскивания для загрузки файлов. В реальности кнопка выбора файла и поле для перетаскивания это разные не вложенные друг в друга теги. Нужно сделать так, чтобы оба этих способа запускали один и тот же обработчик загрузки файлов.

Пока сделал две директивы ng-file="upload1" и ng-droparea="upload1". Как лучше их связать?

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

P.S. Пока видятся два варианта: общаться через модель в корневой области видимости (вотчить ее изменения). Или использовать emit в корневую область и из нее рассылать всем broadcast

nerv_ 16.07.2013 11:42

Цитата:

Сообщение от Shitbox2
Нужно сделать так, чтобы оба этих способа запускали один и тот же обработчик загрузки файлов.

<element ng-file="upload1" ng-upload><element>
...
<element ng-droparea="upload1" ng-upload><element>

?

nerv_ 16.07.2013 20:52

постом выше ерудну сморозил :) дело было утром )
Цитата:

Сообщение от Shitbox2
В реальности кнопка выбора файла и поле для перетаскивания это разные не вложенные друг в друга теги.

и, возможно, разные scope

Цитата:

Сообщение от Shitbox2
P.S. Пока видятся два варианта: общаться через модель в корневой области видимости (вотчить ее изменения). Или использовать emit в корневую область и из нее рассылать всем broadcast

как вариант создать сервис

В моем примере, сервис аккумулирует коллбеки и запускает их по вызову метода сервиса:
<!DOCTYPE HTML>
<html id="ng-app" ng-app="app"> <!-- id="ng-app" IE<8 -->
<head>

    <script src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
    <script>

        var app = angular.module( 'app', []);

        app.factory( '$drag', function() {
            return {
                callbacks: [],
                action: function() {
                    this.callbacks.forEach(function( callback ) {
                        callback();
                    });
                }
            };
        });

        app.controller( 'scope2', function( $scope, $drag ) {
            $scope.action = function() { $drag.action() };
            $drag.callbacks.push(function() {
                alert( 'scope2' );
            });
        });

        app.controller( 'scope3', function( $scope, $drag ) {
            $scope.action = function() { $drag.action() };
            $drag.callbacks.push(function() {
                alert( 'scope3' );
            });
        });

        app.controller( 'scope4', function( $scope, $drag ) {
            $scope.action = function() { $drag.action() };
            $drag.callbacks.push(function() {
                alert( 'scope4' );
            });
        });

    </script>
</head>
<body ng-controller="scope2">
<input type="button" ng-click="action()" value="$scope2.action()">

<div ng-controller="scope3">
    <input type="button" ng-click="action()" value="$scope3.action()">

    <div ng-controller="scope4">
        <input type="button" ng-click="action()" value="$scope4.action()">

    </div>
</div>

</body>
</html>

Shitbox2 18.07.2013 01:53

Как вариант. Пока, правда пробую вариант с общим контроллером, который можно указать при определении директивы, но там непонятно...

nerv_ 19.07.2013 01:22

случайно наткнулся http://odetocode.com/blogs/scott/arc...directive.aspx

Shitbox2 23.07.2013 04:25

Познавательно! У меня нечто похожее. Мой пример в последнем сообщении: https://github.com/angular/angular.js/issues/1236
Думаю, лучший вариант, сделать универсальную директиву для загрузки файлов. Применяешь на кнопку — открывается диалоговое окно, на область — драг энд дроп.

Shitbox2 23.07.2013 07:10

Еще придумал вариант с общим сервисом. Создается сервис Global = {files: [...]}
Директивы выбора файла отправляют объекты файлов в него, а к нему уже обращаешься из разных контроллеров.

nerv_ 24.07.2013 20:02

Цитата:

Сообщение от Shitbox2
Еще придумал вариант с общим сервисом. Создается сервис Global = {files: [...]}
Директивы выбора файла отправляют объекты файлов в него, а к нему уже обращаешься из разных контроллеров.

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

Shitbox2 03.08.2013 10:38

Попался фиддл на эту тему: http://jsfiddle.net/simpulton/huKHQ/

И здесь немного про сервис http://plnkr.co/edit/fQMwfI5d7nikjhXTXSC6?p=preview

nerv_ 05.08.2013 03:03

Написал заготовку для загрузки файлов (html5, drag-n-drop, multimple)

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

Сервисы:
- $fileStorage - файловое хранилище. Туда добавляются файлы, после того, как они были "сброшены и пойманы", либо выбраны в инпуте. Есть возможность фильтровать добавление в хранилище.
- $fileUploader - загрузчик файлов. Помещает файлы в очередь, после чего загружает их оттуда.
- $fileTransport - транспорт. Планирую xhr2 + iframe. На данный момент реализовано только первое.


$fileStorage
свойства:
- files - массив файлов
методы:
- add - добавить в хранилище
- remove - удалить по индексу
- removeAll - удалить все
коллбеки:
- filter: function( file ) { - вызывается до добавления файла в хранилище. true - добавить, false - нет
- onAfterAddingFiles - вызывается после добавления файлов в хранилище. На этом этапе можно читать файлы, делать превьюшки и т.п.


$fileUploader
свойства:
- url: общий для всех файлов. Можно индивидуализировать для каждого файла, после добавления файла в хранилище
- alias - псевдоним, под которым сервер увидит файл. Общий для всех файлов. Можно индивидуализировать для каждого файла, после добавления файла в хранилище
- queue - очередь файлов
методы:
- addToQueue - добавляет файлы в очередь загрузки
- removeFromQueue - удаляет файл из очереди по индексу
- clearQueue - очищает очередь
- uploadItem - загружает файл по индексу
- uploadAll - загружает все файлы в очереди
коллбеки:
- progress - индикация загрузки файла
- success - успешная загрузка
- error - ошибка при загрузке
- complete - загрузка завершена
Надо подумать над тем, что должно приходить в качестве параметров в эти функции. На данный момент только xhr.

В случае выбора >1 файла, файлы будут загружаться по очереди.

http://learn.javascript.ru/play/IhSxR

p.s.: кроме хрома нигде не проверял


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