• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

AngularJS - custom directive na input type=file

Object Storage Arubacloud
0 głosów
287 wizyt
pytanie zadane 16 marca 2023 w JavaScript przez KonTar Początkujący (440 p.)

Cześć! smiley

w AngularJS mam taki dziwny problem z przyciskiem "wybierz plik". Jak wybieram plik o tej samej nazwie po raz drugi i kolejny, to nie może się on załadować do przeglądarki do pamięci. Ogólnie widzę że zmiana nazwy pliku wyzwala jego upload, bo występuje wtedy changeEvent, a chciałbym żeby ładował plik za każdym razem, kiedy zamykane jest okienko.


Ktoś tu może jest przekozakiem z AngularJS/javascriptu i powie gdzie leży problem?laugh

Poniżej kod....

html

<input type="file" name="file" fileread="$ctrl.file" multiple="multiple" class="ng-isolate-scope">

fileupload.js

var main = angular.module('main');

main.directive("fileread", [function () {
    return {
        restrict: 'A',
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                scope.fileread = [];
                for (let i = 0; i < changeEvent.target.files.length; i++) {
                    scope.fileread.push({ fileName: changeEvent.target.files[i].name });
                }

                for (let i = 0; i < changeEvent.target.files.length; i++) {
                    let reader = new FileReader();
                    reader.onload = function (loadEvent) {
                        scope.$apply(() => {
                            scope.fileread[i].content = loadEvent.target.result.split(";base64,").pop();
                        });
                    };
                    reader.readAsDataURL(changeEvent.target.files[i]);
                }
            });
        }
    };
}]);

 

Z góry dziękuję za pomoc!
 

komentarz 16 marca 2023 przez ScriptyChris Mędrzec (190,190 p.)

Próbowałeś podpiąć się na input event (zamiast change)?

komentarz 16 marca 2023 przez KonTar Początkujący (440 p.)

Z tego co obserwuję to zastąpienie change na input nie zmienia działania samego mechanizmu :(

main.directive("fileread", [function () {
    return {
        restrict: 'A',
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("input", function (inputEvent) {
                scope.fileread = [];
                for (let i = 0; i < inputEvent.target.files.length; i++) {
                    scope.fileread.push({ fileName: inputEvent.target.files[i].name });
                }

                for (let i = 0; i < inputEvent.target.files.length; i++) {
                    let reader = new FileReader();
                    reader.onload = function (loadEvent) {
                        scope.$apply(() => {
                            scope.fileread[i].content = loadEvent.target.result.split(";base64,").pop();
                        });
                    };
                    reader.readAsDataURL(inputEvent.target.files[i]);
                }
            });
        }
    };
}]);

2 odpowiedzi

0 głosów
odpowiedź 20 marca 2023 przez kozacko Obywatel (1,580 p.)
wybrane 21 marca 2023 przez KonTar
 
Najlepsza

Wygląda na to, że plik nie jest ładowany do pamięci przeglądarki z powodu przypisywania do scope.fileread pustej tablicy za każdym razem, gdy zmieniasz plik. To powoduje usunięcie poprzednio wybranych plików z pamięci przeglądarki. Aby rozwiązać ten problem, możesz usunąć linię scope.fileread = []; i zmienić pętlę na:
 

for (let i = 0; i < changeEvent.target.files.length; i++) {
    scope.fileread.push({ fileName: changeEvent.target.files[i].name });
    let reader = new FileReader();
    reader.onload = function (loadEvent) {
        scope.$apply(() => {
            scope.fileread[i].content = loadEvent.target.result.split(";base64,").pop();
        });
    };
    reader.readAsDataURL(changeEvent.target.files[i]);
}

To powinno pozwolić zachować już wczytane pliki w pamięci przeglądarki i dodawać kolejne pliki do listy.

komentarz 21 marca 2023 przez KonTar Początkujący (440 p.)
Dzięki za podpowiedź! Generalnie pliki ładują się do pamięci, bo w inpucie mamy atrybut: multiple="multiple", więc wybieramy wiele plików za każdym razem, więc tutaj raczej nie musiałem nic zmieniać. Ogólnie udało się rozwiązać problem, ale to opisze może w odpowiedzi do pytania :)
+2 głosów
odpowiedź 21 marca 2023 przez KonTar Początkujący (440 p.)

Problem udało się rozwiązać na podstawie dwóch spostrzeżeń.

  • event "click" wywołujemy przed "change" na inputcie,
  • przez każdy event możemy odwołać się do konkretnego inputa przez "event.target".

Okazało się, że wystarczyło po każdym kliknięciu usuwać value z inputa, żeby każdy wskazany plik był tak jakby nowy. W skrócie trzeba było resetować aktualny stan inputa, żeby wywołał się change. Pewnie są lepsze sposoby na  to rozwiązanie, ale cóż...smiley

<input type="file" name="file" fileread="$ctrl.file" ng-click="$ctrl.cleanFileCache($event)" multiple="multiple" />
    $ctrl.cleanFileCache = function (clickEvent) {
        if (clickEvent.target.files.length > 0) {
            clickEvent.target.value = null;
            $ctrl.file = [];
        }
    };

 

Podobne pytania

0 głosów
3 odpowiedzi 256 wizyt
pytanie zadane 16 stycznia 2017 w JavaScript przez Captivity Obywatel (1,030 p.)
–1 głos
2 odpowiedzi 380 wizyt
0 głosów
0 odpowiedzi 174 wizyt
pytanie zadane 3 maja 2018 w JavaScript przez LockeLamora Użytkownik (740 p.)

92,555 zapytań

141,403 odpowiedzi

319,554 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...