Angular.js: mendukung pengikatan input[type=file]

Dibuat pada 18 Sep 2012  ·  145Komentar  ·  Sumber: angular/angular.js

hai mencoba melakukan pengunggahan file sederhana :) tetapi input type=file sepertinya tidak mengikat saya mencoba hg-model-instant tetapi tidak mendapatkan apa-apa, bahkan ditingkatkan ke 1.0.2 dan tidak ada apa-apa

forms moderate not core feature

Komentar yang paling membantu

Solusi ini tergantung pada filereader yang diimplementasikan:

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

Anda kemudian harus melakukan beberapa hal xhr sendiri tetapi saya percaya bahwa ini di luar gui binding dan lebih banyak logika pemrosesan.

dan jika Anda kurang imajinasi:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

Ini berfungsi karena xhr2 (http://www.html5rocks.com/en/tutorials/file/xhr2) dan mohon maafkan contoh url unggahan yang panjang, ini adalah titik akhir dokumen couchdb (lampiran).

Semua 145 komentar

Tidak ada pengikatan default yang disediakan oleh angular ke input type=file.

Tapi kemudian, input file hanya nyata untuk javascript, satu-satunya manfaat pengikatan seperti itu dapat membantu adalah membersihkan input file. (Angular juga tidak memberikan dukungan kerangka kerja untuk mengunggah file ajax sekarang, saya percaya)

@coli : itu tidak

Masuk akal untuk dapat menangkap acara onchange pada input[file].

Di https://github.com/lgersman/jquery.orangevolt-ampere kami memiliki skenario yang persis seperti itu: unggahan file melalui XMLHTTPRequest V2.
Oleh karena itu kami menerapkan arahan kami sendiri untuk menangkap peristiwa perubahan input[file] untuk menyelesaikan unggahan file tanpa memuat ulang halaman.

Saya akan senang melihat fitur itu di angularjs!

Apakah ada kemajuan yang dibuat dengan mengikat input jenis file? Saya telah mencari solusi dan sepertinya tidak dapat menemukan solusi yang berfungsi ...

solusi saya hanya Ajax alih-alih permintaan atau http.post

Dikirim dari iPad saya

Pada 1 Maret 2013, pukul 19:16, "jgoldber" < [email protected] [email protected] > menulis:

Apakah ada kemajuan yang dibuat dengan mengikat input jenis file? Saya telah mencari solusi dan sepertinya tidak dapat menemukannya.


Balas email ini secara langsung atau lihat di Gi tHubhttps://github.com/angular/angular.js/issues/1375#issuecomment -14321221.

Solusi terbaik yang saya temukan: http://jsfiddle.net/marcenuc/ADukg/49/ . Silakan bagikan jika Anda menemukan solusi yang lebih baik.

Ya, ini benar-benar perlu dilihat; dapat memilih & mengunggah file cukup penting untuk sebagian besar aplikasi web, jadi mendukung input ini adalah fitur yang cukup jelas hilang.

Menabrak. Ini perlu ditambahkan ke tonggak sejarah.

Teriakan lain untuk mendukung ini.

ng-model file dapat menetapkan nilai ke file dari HTML5 File API, ada polyfill Flash dan Silverlight untuk IE8/IE9

Ya, atur nilainya ke file atau ke elemen input (berisi referensi ke file)

Solusi ini tergantung pada filereader yang diimplementasikan:

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

Anda kemudian harus melakukan beberapa hal xhr sendiri tetapi saya percaya bahwa ini di luar gui binding dan lebih banyak logika pemrosesan.

dan jika Anda kurang imajinasi:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

Ini berfungsi karena xhr2 (http://www.html5rocks.com/en/tutorials/file/xhr2) dan mohon maafkan contoh url unggahan yang panjang, ini adalah titik akhir dokumen couchdb (lampiran).

Dimungkinkan untuk membuat ini berfungsi di IE8/9 dengan menggabungkan FileReader Polyfill berbasis flash ini https://github.com/Jahdrien/FileReader dan polyfill FormData js murni ini yang bergantung pada FileReader https://github.com/francois2metz/ html5-formdata. _update_ Moxie adalah polyfill yang lebih baik

Solusi saya cukup samar, setidaknya sama samarnya dengan jsfiddle di atas tempat prototipe pengontrol dikotori ...

Di pengontrol:

    $scope.updateImage = '(' + function () {
      alert('moo');
    }.toString() + ')();';

Merangkai panggilan balik onchange yang saya inginkan dan membungkusnya dengan penutupan.

   <input type="file" name="image" onchange="{{updateImage}}" ng-model="image">

Masukkan ke DOM menggunakan Angular

Tidak terlalu cantik tetapi berfungsi di Webkit. Saya tidak melakukan pengujian lintas browser.

Saya menggunakan 1.0.5 dan masih rusak. Kami menggunakan contoh Jgoldber dan mengubahnya sedikit:
http://jsfiddle.net/ADukg/2589/

Contoh ini hanya akan berfungsi untuk satu pengontrol, jadi jika Anda memiliki beberapa pengontrol, masing-masing dengan input file, Anda perlu membuat beberapa perubahan.

Belum mengujinya di IE, tetapi tebakan saya (mengetahui IE) adalah itu tidak akan berfungsi.

Dengan asumsi bahwa Anda hanya ingin memanggil fungsi dalam lingkup Anda yang menggunakan elemen input sebagai argumen, ini cukup mudah untuk diterapkan dalam arahan:

http://jsfiddle.net/neilsarkar/vQzKJ/

(dimodifikasi dari jsfiddle di atas, terima kasih @programmist)

'use strict';

function filesModelDirective(){
  return {
    controller: function($parse, $element, $attrs, $scope){
      var exp = $parse($attrs.filesModel);

      $element.on('change', function(){
        exp.assign($scope, this.files);
        $scope.$apply();
      });
    }
  };
}

konfigurasi:

angular.module(...).directive('filesModel', filesModelDirective)

penggunaan:

<input type="file" files-model="someObject.files" multiple>

Tolong segera perbaiki ini.

Masih mengalami masalah .. di beberapa versi berfungsi tetapi tetap tidak didukung

Sejak 1.5.0 $digest harus dipanggil jika Anda menggunakan solusi onchange:

<input type="file" onchange="angular.element(this).scope().myController.uploadFile(this.files[0]); angular.element(this).scope().$digest();">

+1 untuk dukungan yang lebih baik pada ng-change dan input/file. Kasus penggunaan: sebagai pengunggah gambar, saya ingin dapat mengedit gambar itu (mengubah ukuran dan memotong) sebelum mengunggah untuk tampilan yang optimal. Implementasi: browse ke gambar (menggunakan input/file) dan pada acara onchange pindahkan file ke kanvas dan edit dengan fabricjs. Saya tidak bisa memikirkan implementasi perubahan yang tidak aktif.

cztomsik - Saya menggunakan 1.0.7 dan saya tidak dapat membuat solusi Anda berfungsi - fungsi lingkup (ini) diselesaikan dengan baik, tetapi pengontrol tidak dapat ditemukan, fungsi uploadFile terdaftar sebagai anggota lingkup (ini).

Omong-omong, saya memiliki sedikit modifikasi pada tekniknya, yang tampaknya berhasil untuk saya (saya masih tidak tahu mengapa saya memiliki:

< input type="file" name="file" ng-model="file" onchange="invokeUploadFile(this)"/ >

var memanggilUploadFile = fungsi(itu) {
angular.element(itu).scope().uploadFile(itu)
angular.element(that).scope().$digest();
}

Bisakah Anda memberikan jsfiddle/plunker?
Terima kasih


    1. 2013 v 18:17, tb01923 [email protected] :

+1 untuk dukungan yang lebih baik pada ng-change dan input/file. Kasus penggunaan: sebagai pengunggah gambar, saya ingin dapat mengedit gambar itu (mengubah ukuran dan memotong) sebelum mengunggah untuk tampilan yang optimal. Implementasi: browse ke gambar (menggunakan input/file) dan pada acara onchange pindahkan file ke kanvas dan edit dengan fabricjs. Saya tidak bisa memikirkan implementasi perubahan yang tidak aktif.

cztomsik - Saya menggunakan 1.0.7 dan saya tidak dapat membuat solusi Anda berfungsi - fungsi lingkup (ini) diselesaikan dengan baik, tetapi pengontrol tidak dapat ditemukan, fungsi uploadFile terdaftar sebagai anggota objek lingkup (ini) tetapi ketika saya hapus pengontrol yang saya dapatkan

ReferenceError Tidak Tertangkap: uploadFile tidak ditentukan blah.js:15
$scope.uploadFile bla.js:15
panggilScope bla.js:4
dalam perubahan


Balas email ini secara langsung atau lihat di GitHub.

+1. Membutuhkannya untuk memulai unggahan file HTML5 saat pengguna memilih file. Sangat mudah untuk mengatasinya, tetapi saya berharap ini berhasil.

+1. tolong terapkan, tidak mengimplementasikannya sama sekali tidak intuitif.

+1

+1

Ayo guys.. sudah lebih dari setahun dan angular 1.2.0 masih tidak memiliki binding file input ... Saya tidak mengerti mengapa fitur itu tidak ditambahkan? Ada beberapa solusi yang baik untuk implementasi. Saya ingin tanggapan anggota tim sudut tentang masalah ini.

Hanya untuk mengutip salah satu solusi terbaik (saya tahu ini adalah pengikatan data satu arah tetapi masih lebih baik daripada tidak sama sekali, validasi dan pembaruan model berfungsi bahkan di IE7):

Definisi

  /**
   * <strong i="8">@ngdoc</strong> inputType
   * <strong i="9">@name</strong> angular.module.ng.$compileProvider.directive.input.file
   *
   * <strong i="10">@description</strong>
   * HTML file input field.
   *
   * <strong i="11">@param</strong> {string} ngModel Assignable angular expression to data-bind to.
   * <strong i="12">@param</strong> {string} multiple Allows multiple files selection.
   * <strong i="13">@param</strong> {string=} name Property name of the form under which the 
                                control is published.
   *
   * <strong i="14">@example</strong>
      <doc:example>
        <doc:source>
         <script>
           function Ctrl($scope) {
           }
         </script>
         <form name="myForm" ng-controller="Ctrl">
           file: <input type="file" ng-model="file"> single file selection.<br/>
           files: <input type="file" ng-model="files" multiple> multi-file selection.<br/>
           <tt>file.name = {{file.name}}</tt><br/>
           <tt>files.length = {{files.length}}</tt><br/>
          </form>
        </doc:source>
        <doc:scenario>
          it('should change state', function() {
            expect(binding('file.name')).toBeUndefined();

            input('file').select('a file name');
            expect(binding('file.name')).toEqual('a file name');
          });
        </doc:scenario>
      </doc:example>
   */
  'file': fileInputType,

Fungsi

function fileInputType(scope, element, attr, ctrl) {
  element.bind('change', function() {
    scope.$apply(function() {
      var files = element[0].files,
          isValid = true;

      if (msie < 10) {
        files = [element[0].value];
      }

      if (attr.accept) {
        var i, j, acceptType, fileType,
            types = map(attr.accept.split(','), function(t) { return trim(t).split('/'); });
        for (i = 0; i < files.length && isValid; ++i) {
          fileType = files[i].type.split('/');
          isValid = false;
          for (j = 0; j < types.length && !isValid; ++j) {
            acceptType = types[j];
            isValid = acceptType[0] === fileType[0] && (acceptType[1] === '*' || acceptType[1] === fileType[1]);
          }
        }
      }
      ctrl.$setValidity('file', isValid);

      var viewValue;
      if (isValid) viewValue = attr.multiple ? files : files[0];
      ctrl.$setViewValue(viewValue);
    });
  });
}

+1

+1

@ntrp Mengapa Anda tidak melakukan PR perubahan ini?

Perubahan itu perlu dijelaskan sedikit dan diuji, saya tidak punya waktu saat ini untuk melakukannya.

+1

+1

-1:trollface:

bercanda +1

+1

+1

+1

+1

+1

input[type=file] sebenarnya bukan hal yang mengikat 2 arah, kecuali kami secara eksplisit menggunakan File API, yang tidak tersedia di semua browser target. Menambahkan ini ke ng-model tidak masuk akal, tetapi ada banyak plugin yang mendukung beberapa variasi fungsi ini. Apakah kita tidak apa-apa untuk hanya mendelegasikan ini ke plugin untuk sementara waktu?

http://caniuse.com/fileapi

@caitp Benar, tetapi masuk akal untuk dapat mengikat ke acara perubahan, melalui ng-change, yang tidak berfungsi.

Hal lain yang tidak berfungsi adalah validasi formulir. Saya pikir dukungan file harus diterapkan untuk browser baru dengan fallback pengikatan data satu arah untuk yang lama. Jika solusi ini tidak dapat dijalankan, menurut pendapat saya, itu harus dinyatakan dengan jelas di wiki mengapa fungsionalitas tidak diterapkan dan bagaimana memecahkan masalah yang disebabkan oleh kurangnya dukungan ini. Saya ingat kehilangan banyak waktu sebelum menyelesaikan kebutuhan file input saya ketika saya pertama kali menggunakannya.

Masalahnya, nama file tidak terikat ke model, dan tidak masuk akal untuk mengikatnya ke model. Setiap properti antarmuka File hanya dapat dibaca, dan antarmuka FileList hanya kumpulan File. Tidak ada kapasitas untuk pengikatan 2 arah, jadi tidak ada alasan nyata untuk menggunakan ng-model untuk ini sejak awal. Ini cukup sederhana untuk mengikat ke acara change sebagai gantinya, dan Anda dapat dengan mudah menulis arahan untuk menambahkan fungsionalitas itu sehingga Anda dapat menggunakannya secara deklaratif jika Anda membutuhkannya.

Tetapi bagaimana masuk akal untuk menjadikan ini bagian dari model-ng ketika tidak memiliki kapasitas untuk mengikuti perilaku model-ng?

Tidak ada alasan seseorang tidak dapat membuat antarmuka khusus untuk file, dan angular dapat melakukan ini di beberapa titik, tetapi menurut saya itu tidak masuk akal dengan ng-model. Saya tidak tahu apa yang dipikirkan pengembang lain tentang ini, mereka mungkin setuju atau tidak. Tetapi dari sudut pandang saya, arahan terpisah akan lebih masuk akal, karena input[type=file] tidak cocok dengan ng-model

  • Tidak ada nilai input file yang dapat ditulis dari konteks skrip
  • Kami tidak memiliki cara nyata untuk melakukan validasi di sini tanpa File API (yang tidak didukung di beberapa browser target), pada dasarnya browser melakukan ini untuk kami. --- dengan pengecualian validasi ngRequired

Satu-satunya hal yang benar-benar dapat kami lakukan untuk input[type=file] adalah $setViewValue ketika nilainya berubah (yang sebenarnya tidak masuk akal), dan entah bagaimana mengubah ngModel untuk mengabaikan perubahan pada nilai model yang disebabkan oleh perubahan skrip (atau pada dasarnya cukup nonaktifkan $watch sepenuhnya). Untuk validasi, yang bisa kami dukung hanyalah ng-required, maksud saya apa lagi yang bisa kami lakukan di sana?

Saya ingin dapat mendukung input file dengan ngModel juga, tetapi saya tidak melihat cara kerjanya, itu tidak cocok dengan antarmuka ngModel.

Saya setuju dengan pernyataan ini tetapi kemudian, seperti yang saya katakan sebelumnya, kita perlu lebih menekankan hal ini di wiki atau umumnya dalam dokumentasi sehingga pengembang tahu apa yang harus mereka lakukan untuk mencapai fungsionalitas yang mereka butuhkan.

@ntrp well docs tambalan lebih dari diterima, dan saya akan dengan senang hati meninjau jika Anda mengirimkannya :)

Bisakah menambahkan arahan spesifik di angular itu sendiri menjadi solusi?

Saya setuju dengan pernyataan sebelumnya, tetapi tampaknya agak aneh bahwa a
kerangka kerja seperti sudut tidak memiliki cara yang jelas dan bersih untuk dicapai
ini...
Ini mungkin adalah hal yang paling membingungkan yang harus saya hadapi ketika mencoba
unggah file...

Ah ok @caitp , saya membaca beberapa waktu lalu bahwa permintaan tarik wiki tidak benar-benar dievaluasi secara aktif sehingga saya tidak repot-repot berkontribusi. Jika saya mendapatkan waktu luang segera saya akan dengan senang hati berkontribusi kemudian :) terima kasih.

Saya tidak menyadari bahwa arahan ngChange mengharuskan ngModel untuk hadir juga, yang saya kira adalah mengapa ada begitu banyak diskusi tentang ngModel di sini (dan itulah sebabnya saya mendapatkan kesalahan ini ). Saya setuju bahwa pengikatan 2 arah pada input[type=file] tidak masuk akal.

Tapi apa alasan sebenarnya mengapa ngModel dibutuhkan oleh ngChange? Dalam pikiran saya, sangat masuk akal untuk dapat mengikat ke acara perubahan bidang input[type=file], katakanlah jika Anda ingin mengirimkan formulir secara otomatis setelah file dipilih. Dalam kasus seperti itu, saya tidak terlalu peduli berapa nilai bidangnya. Saya hanya peduli bahwa itu berubah. Cara terbaik yang saya temukan untuk menangani hal seperti itu adalah melalui solusi yang disebutkan di atas oleh @cztomsik :

onchange="angular.element(this).scope().fileChangedHandler()"

Dan itu tidak benar-benar terasa seperti solusi terbaik.

ng-change , meskipun dinamai mirip dengan direktif event handler lainnya, sebenarnya bukan handler untuk event change . Itu hanya menambahkan $viewChangeListener ke ngModelController, yang dipicu setiap kali $setViewValue dipanggil.

Saya setuju itu adalah nama yang disayangkan

Ini adalah penipuan #1236 yang ditutup dengan komentar ini: https://github.com/angular/angular.js/issues/1236#issuecomment -29115377

kecuali kami melihat proposal tentang cara menerapkan ini sehingga ringan, namun fungsional dan tidak memerlukan gaya ux yang dipaksakan ke pengguna framewok, kami akan mempertimbangkannya. Namun saat ini, kami berpikir bahwa masalah pengunggahan file cukup kompleks sehingga perlu diselesaikan sebagai modul seoarate, kemungkinan di luar inti.

+1

@IgorMinar lihat di sini, agak kotor, tetapi contoh implementasi yang sangat menarik: https://github.com/danialfarid/angular-file-upload. @danialfarid membuat kemajuan besar dengan ini.

Periksa bagaimana ini menjadi masalah untuk semua, beberapa masalah dibuka dengan beberapa komentar. Anda harus menyediakan modul ngUpload untuk kami : smile:. Mungkin Anda dapat memberikan implementasi html5 dan menambahkan contoh penggunaan dengan https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills#file -api ke http://docs.angularjs.org/guide /yaitu.

Bagaimana Anda berpikir untuk menyelesaikannya?

+1

+1

+1

+1

+1

+1

+1

+1

Wow, agak memalukan pada tahap ini.

+1

Sangat tidak mungkin memiliki binding 2 arah untuk input file, tentu saja ketika browser target tidak semuanya mendukung File API (http://caniuse.com/fileapi) --- Tetapi bahkan ketika mereka bisa, input[type=file] tidak terlalu cocok dengan itu. Pengikatan 2 arah benar-benar tidak mungkin

Maaf tapi ini lebih merupakan masalah/fitur keamanan platform web daripada yang lainnya. Jika itu bisa dilakukan, itu akan dilakukan

@caitp Saya benar-benar mengerti apa yang Anda katakan tetapi "ini lebih merupakan fitur masalah/keamanan platform web daripada yang lainnya" adalah pernyataan yang sedikit konyol. Inti dari framework adalah untuk memfasilitasi kekurangan browser, web spec, dan berbagai inkonsistensi. Ini tentu saja merupakan satu tempat di mana peringatan untuk fileAPI sudah memadai. Ada solusi sekarang, mengapa tidak melipatnya?

Sesuatu yang sederhana seperti pembungkus untuk ini misalnya akan menjadi awal.

Mengingat arah yang dituju Angular 2.0 (mengubah idiom angular-only, non-ECMA), saya tidak berpikir keterbatasan "platform web" harus menjadi perhatian.

@semua orang: Apa yang dilakukan Ember dalam kasus ini?

Sunting: menghapus "wajib" dari pernyataan transpiling.

_Hanya klarifikasi cepat._ Membangun aplikasi Angular 2.0 tidak memerlukan bahasa transpil atau idiom non-ECMA. Anda dapat menggunakan kode ES5 biasa saja. Jika Anda ingin membangun sumber Angular 2.0, maka Anda perlu menggunakan traceur untuk mengkompilasi. Secara alami, Anda dapat menggunakan traceur untuk membangun aplikasi Anda sendiri dan memanfaatkan fitur yang sama yang kami gunakan di dalam Angular, tetapi itu sepenuhnya opsional. Maaf jika ada beberapa kebingungan pada saat itu dalam pengumuman kami.

@EisenbergEffect Saya buruk. Saya tahu itu dan seharusnya mengoreksi lebih baik. Tidak ada kopi!

Kerangka kerja tidak dapat benar-benar mengatasi keterbatasan platform web. Seperti, kita tidak bisa memaksa browser untuk membiarkan kita menulis ke atribut IDL readonly (yang benar-benar merusak ikatan 2 arah untuk file), dan kita tidak bisa memaksa browser untuk mengekspos sistem file kepada kita, yang benar-benar mencegah kita melakukan sesuatu yang menarik dengan itu

@caitp Saya telah mengikuti masalah ini untuk beberapa waktu sekarang. Saya pikir tampaknya ada cukup keinginan komunitas untuk Angular untuk mendukung input pemilihan file sederhana. Saat ini (kecuali saya salah), membangun aplikasi sepele yang menerima file dan mengunggahnya melalui XHR menggunakan Angular tidak memiliki pola yang disarankan untuk diikuti? Kedengarannya seperti fitur yang setidaknya patut mendapat perhatian selain, "maaf tidak dapat melakukannya karena pengikatan dua arah tidak masuk akal di sini."

Mungkin kita dapat mengarahkan kembali percakapan ini ke, "Bagaimana sudut dapat mendukung ini?" alih-alih, "Itu tidak akan cocok dengan pola kita saat ini."

Mengikat ke input file pasti mungkin, saya sudah melakukannya di proyek sebelumnya untuk AngularJS sebenarnya.

Fakta bahwa Anda tidak dapat mengikat dua arah dengan input file adalah fitur keamanan, dan itu masuk akal. Penulis tidak akan pernah dapat mengatur jalur file melalui skrip, tetapi mengapa tidak mengikatnya satu arah saja?

Tentu itu merusak paradigma, tetapi siapa yang peduli jika itu berarti Anda mendapatkan perubahan dan kemampuan untuk mengakses file melalui API file tanpa peretasan? jQuery dapat mengikat ke acara perubahan pada input file, apakah cara Angular begitu sakral sehingga kita tidak bisa hanya mengikatnya di dalam pengontrol? Apakah keterbatasan teknis dengan arsitektur atau hanya hambatan ideologis?

Setuju, saya kurang peduli dengan penjilidan 2 arah. Saya hanya ingin memposting file dengan sisa dokumen saya tanpa melompati rintangan.

Pada tanggal 20 Mei 2014, pukul 07.53, Justin Arruda < [email protected] [email protected] > menulis:

@c aitphttps://github.com/caitp Saya telah mengikuti masalah ini untuk beberapa waktu sekarang. Saya pikir tampaknya ada cukup keinginan komunitas untuk Angular untuk mendukung input pemilihan file sederhana. Saat ini (kecuali saya salah), membangun aplikasi sepele yang menerima file dan mengunggahnya melalui XHR menggunakan Angular tidak memiliki pola resmi untuk diikuti? Bukankah itu terdengar seperti fitur yang setidaknya perlu mendapat perhatian selain, "maaf tidak dapat melakukannya karena pengikatan dua arah tidak masuk akal di sini."

Mungkin kita dapat mengarahkan kembali percakapan ini ke, "Bagaimana sudut dapat mendukung ini?" alih-alih, "Itu tidak akan cocok dengan pola kita saat ini."


Balas email ini secara langsung atau lihat di Gi tHubhttps://github.com/angular/angular.js/issues/1375#issuecomment -43636326.

Kemudian Anda memiliki satu kasus di mana ng-model berperilaku sangat berbeda untuk satu kontrol formulir tertentu, dan kemudian Anda memiliki orang-orang yang mengajukan bug seperti "kenapa kontrol formulir mengirim file yang salah ketika saya mengubah nilainya menjadi "foobarblah.txt" atau apa pun. API tidak konsisten -> buruk.

ngModel tidak sepenuhnya ideal untuk hal ini secara khusus karena itu berarti kami memiliki pola khusus untuk disesuaikan, dan sangat sulit bagi pembuat aplikasi untuk mematikannya. Ada solusi untuk ini di angular.dart dan prototipe v2.0.0, jadi ini akan lebih baik di masa mendatang. Tapi kami benar-benar tidak dapat menambahkan perilaku ng-model lain yang mengabaikan semua yang dilakukan ng-model saat ini, itu tidak masuk akal

menerima file dan mengunggahnya melalui XHR menggunakan Angular

@guruward kami tidak dapat mendukung ini di semua browser target kami untuk 1.x tanpa memaksa orang untuk menggunakan polifill gelombang kejut atau sejenisnya. Ada modul pihak ketiga yang mengizinkan ini, dan mereka dapat digunakan sebagai gantinya. angular-file-upload mengirimkan versi asli shockwave polyfill dan html5 secara bersamaan, dan memilih yang tepat. Jadi itu bukan solusi yang buruk, sangat disarankan jika Anda ingin melakukan ini.

Tapi saya tidak yakin itu sesuatu yang bisa kita masukkan ke dalam inti, Anda harus bertanya kepada Igor apa pendapatnya tentang pengiriman polyfill gelombang kejut di inti.

Saya tidak mengatakan ini adalah kasus penggunaan yang tidak akan pernah ingin dilakukan orang, saya bisa mengerti keinginan untuk melakukan ini, saya hanya mengatakan itu tidak cocok dengan pola ngModel, dan mengharuskan kita untuk menambahkan beberapa cruft ekstra untuk mendukung semua browser target, sehingga merusak kerangka kerja seperti itu.

Apa salahnya menggunakan modul pihak ketiga untuk ini?

Polyfill ini tidak memerlukan flash.

@jreading itu bukan polyfill, dan dulu dikirim dengan pengunggah flash, mungkin masih ada di suatu tempat.

Apa yang dilakukannya adalah mengandalkan File API, yang tidak tersedia di semua browser target, dan karena itu bermasalah untuk angular 1.x core.

Tanpa API itu, Anda tidak memiliki cara untuk mendapatkan gumpalan file tanpa sesuatu seperti gelombang kejut.

Ini menggunakan iframe alih-alih flash, Anda mungkin memikirkan ini . Alih-alih berdebat semantik, bagaimana dengan peta jalan? Mari kita mulai dengan ng-change pada input file untuk browser yang mendukung file api.

@jreading sayangnya ini tidak membantu browser yang tidak mampu api, termasuk IE9, yang masih didukung. Kami tidak dapat mengirimkan API yang berfungsi pada browser A yang didukung tetapi tidak mendukung browser B di inti tanpa ada solusi untuk orang-orang yang bergantung pada dukungan IE9. Dan tidak, iframe tidak mengekspos konten file sebagai gumpalan dan membuatnya dapat diunggah. Hnggggg.

Ada solusi untuk ini dalam modul pihak ketiga, yang dapat digunakan aplikasi jika mereka merasa cocok. Menempatkan ini di inti A) memberi modul pihak ketiga itu waktu yang lebih sulit, dan B) gagal mendukung semua browser target, jadi ini adalah masalah.

Ini hanya pendapat saya, mungkin Igor atau orang lain akan tidak setuju, tetapi saya pikir itu bukan pendekatan yang tepat di sini.

Apa salahnya menggunakan modul pihak ketiga jika mereka bekerja untuk Anda, dan Anda membutuhkannya?

Tidak pernah benar-benar menyiratkan bahwa gumpalan perlu tersedia untuk pengontrol. Saya mengambil risiko, tetapi kasus penggunaan terbesar yang saya lihat adalah kemampuan untuk mengetahui kapan input file telah berubah dan kemampuan untuk mengirimkannya ke titik akhir istirahat, yang tersedia dengan solusi iframe ini atau file API dan sudut hack.

Modul pihak ke-3 adalah satu-satunya cara atau peningkatan agresif seperti posting blog saya (tidak ada unggahan untuk Anda!!), tetapi saya dapat membalikkan pertanyaan dan bertanya "apa salahnya memiliki api yang lebih baik untuk browser modern?"

"apa salahnya memiliki api yang lebih baik untuk browser modern?"

Argumen ini lemah karena tidak memperhitungkan biaya peluang; masih banyak hal lain yang harus kami (tim inti) kerjakan.

Cukup adil. Hanya terasa seperti celah besar dan buah menggantung rendah.

Masalahnya di sini bukan tentang bagaimana membuatnya bekerja dengan ngModel. Saya pikir ngModel dapat mengekspos FileList dari bidang input ke ruang lingkup, tetapi di arah lain, kami hanya mengizinkan pengaturan model ke nol/tidak terdefinisi untuk didukung. parser/formatter kemungkinan tidak akan melakukan apa pun dan validator hanya akan melakukan hal-hal sederhana seperti memeriksa ada atau tidaknya file.

Masalahnya adalah (seperti yang telah disebutkan sebelumnya) bahwa tanpa dukungan file api melakukan ini dengan benar tidak layak untuk inti mengingat dasar kami adalah IE9 dan polyfilling hal ini tidak mungkin untuk inti.

Selain itu mencoba menangani input ini dengan cara yang tidak kompatibel lintas-browser hanya mempersulit solusi pihak ke-3, yang sekarang harus berjuang/menonaktifkan/menyelesaikan solusi inti.

solusi non-inti yang menangani ini sudah ada dan mereka disebutkan dalam diskusi masalah ini serta dalam masalah sebelumnya

Ada banyak hal lain yang memiliki dampak lebih besar yang ingin kita selesaikan. Saya mengerti bahwa ini adalah kasus yang relatif umum, tetapi saya masih belum mendengar mengapa solusi yang ada tidak cukup?

Bisakah sebagian energi yang dimasukkan ke dalam diskusi ini dialihkan untuk meningkatkan solusi yang ada jika mereka membutuhkannya, atau menciptakan solusi baru yang lebih unggul dari yang sudah ada?

Saya akan menutup ini sama seperti kita menutup #1236. Angular 2 sedang dibangun untuk mendukung browser modern dan dengan dukungan file itu akan tersedia dengan mudah.

Saya hanya ingin tahu kapan acara perubahan terjadi sehingga saya dapat mengakses elemen secara langsung dan mengambil info file dan mengunggah melalui AJAJ.

@bjoshuanoah lalu untuk apa Anda membutuhkan ngModel? Cukup ikat pendengar acara ke input =p

@caitp Saya ingin mengontrol semua yang ada di pengontrol dan bukan dengan arahan.

Jika saya memasukkan ng-change="uploadFile({$event: $event})"

Saya dapat memiliki $scope.uploadFile(event) di controller saya. dan menanganinya di sana.

Kasus penggunaan khusus saya adalah ini: unggah file ke s3, terapkan url ke model saya.

alih-alih saya harus masuk ke ruang lingkup untuk melakukan hal yang sama. Sangat menyebalkan:

<input name="highRes" scope="{{contentOptions.currentValue}}" key="value" type="file" onchange="angular.element(this).scope().setFile(this)">

Saya berharap seseorang akan membunuh masalah ini. jadi kita semua bisa move on :)

Pada 25 Juli 2014, pukul 09:22, Brian < [email protected] [email protected] > menulis:

Saya hanya ingin tahu kapan acara perubahan terjadi sehingga saya dapat mengakses elemen secara langsung dan mengambil info file dan mengunggah melalui AJAJ.


Balas email ini secara langsung atau lihat di Gi tHubhttps://github.com/angular/angular.js/issues/1375#issuecomment -50171714.

+1

+1

+100000000000000

+1

+1

+1

+1

+100500

+1
Saya tidak yakin mengapa Ajax menjadi masalah. Seseorang mungkin ingin memuat data dari file csv pada mesin lokal ke dalam model Angular. Jika ng-change berfungsi dalam input file dalam Angular, ini akan mudah, saat ini tidak . Skenario ini tidak memerlukan Ajax atau API server sama sekali. Saya juga tidak yakin mengapa ini ditutup?

Solusi saya saat ini adalah melakukan hal berikut

 input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

dan di controller saya hanya ada sesuatu seperti

$scope.onFileSet = function(files) { 
// work your magic here 
}

Cukup banyak bau, saya merasa seperti saya bajingan sudut sebagai alat. Wawasan apa pun tentang bagaimana melakukan ini dengan cara yang lebih bersudut akan sangat dihargai.

:hati: :hati:

Ini dia perahu layarnya : :perahu layar:

@samccone Bukankah scope() tidak tersedia saat mode debug dimatikan?

@geetsce Itu benar (dalam 1.3.x dan yang lebih baru)

wah, di tanah 1.2 semuanya baik-baik saja.

@Narretz apakah Anda punya solusi yang lebih baik?

Ini berfungsi untuk saya, ini terinspirasi oleh https://jasonturim.wordpress.com/2013/09/01/angularjs-drag-and-drop

<input type="file" multiple="multiple" data-dbinf-on-files-selected="chooseAFunctionName(selectedFileList)">
<script>
/**Directive to propagate selected files from an HTML input element with type="file"
 * to the surrounding AngularJS controller.
 */
myApp.directive('dbinfOnFilesSelected', [function() {
    return {
        restrict: 'A',
        scope: {
              //attribute data-dbinf-on-files-selected (normalized to dbinfOnFilesSelected) identifies the action
              //to take when file(s) are selected. The '&' says to  execute the expression for attribute
              //data-dbinf-on-files-selected in the context of the parent scope. Note though that this '&'
              //concerns visibility of the properties and functions of the parent scope, it does not
              //fire the parent scope's $digest (dirty checking): use $scope.$apply() to update views
              //(calling scope.$apply() here in the directive had no visible effect for me).
            dbinfOnFilesSelected: '&'
        },
        link: function(scope, element, attr, ctrl) {
            element.bind("change", function()
            {  //match the selected files to the name 'selectedFileList', and
               //execute the code in the data-dbinf-on-files-selected attribute
             scope.dbinfOnFilesSelected({selectedFileList : element[0].files});
            });
        }
    }
}]);

myApp.controller('myController', ['$scope', function($scope) {
    $scope.chooseAFunctionName = function (filelist) {
        for (var i = 0; i < filelist.length; ++i) {
            var file = filelist.item(i);
            //do something with file; remember to call $scope.$apply() to trigger $digest (dirty checking)
            alert(file.name);
           }
    };
}]);
</script>

+1

+1

Itu tidak akan terjadi ... Biarkan saja, biarkan saja ...

+1

Seperti yang dikatakan @samccone ,

input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

Ini bukan cara Angular dalam melakukan sesuatu. Ini aneh.

+1

+1

+1

hey @caitp @Narretz jika kalian mau saya bisa mengerjakan PR untuk ini untuk cabang 1.2x, beri tahu saya jika ini adalah sesuatu yang ingin Anda tambahkan atau tidak. Saya memahami masalah keamanan dan kurangnya dukungan lintas browser sejauh mendapatkan akses ke objek file yang sebenarnya, namun sepertinya dukungan dasar untuk mendeteksi ketika input file telah berubah (melewati acara asli) akan memberikan cukup pengait bagi orang-orang untuk mengerjakan sihir mereka.

Sekali lagi terima kasih atas semua yang Anda lakukan :palm_tree:

+1

+1

+1

+1

+1

ng-file-upload bekerja dengan baik.

+1 untuk @neokyol!! Itu bekerja dengan baik!

fitur umum ini harus secara default di framework

bermanfaat

+1

+1

+1

+1

+1

ini berhasil untuk saya, semoga membantu

angular.module('app', [])
  .controller('MainCtrl', MainCtrl)
  .directive('fileChange', fileChange);

  function MainCtrl($scope) {
    $scope.upload = function () {
      // do something with the file
      alert($scope.file.name);
    };
  }

  function fileChange() {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: {
        fileChange: '&'
      },
      link: function link(scope, element, attrs, ctrl) {
        element.on('change', onChange);

        scope.$on('destroy', function () {
          element.off('change', onChange);
        });

        function onChange() {
          ctrl.$setViewValue(element[0].files[0]);
          scope.fileChange();
        }
      }
    };
  }
<div ng-app="app" ng-controller="MainCtrl">
  <input type="file" file-change="upload()" ng-model="file">
</div>

http://plnkr.co/edit/JYX3Pcq18gH3ol5XSizw?p=preview

+1

+1

+1

+1

+1000000000000000000000000

+1

+1

@dciccale bisa tolong berikan contoh plunker.

+1

+1

+1 Harus ada arahan yang dibangun ke dalam perpustakaan inti untuk ini. Cukup konyol

+1

+1
apakah fitur tersebut dijadwalkan untuk salah satu rilis berikutnya?

+1

+1

Bagaimana ini dalam proyek di mana $scope tidak pernah disuntikkan ke controller. Saya menggunakan laravel angular yang menggunakan cara GULP dan ES6 untuk mendeklarasikan pengontrol.

yaitu

class TestController{
    constructor(API){
        'ngInject';
        this.API = API
    }

    $onInit(){
        this.file = null;
    }
    upload() {
        console.log(this.file)
    }
    fileChanged(elm) {
        console.log('hey')
        this.file = elm.file;
        this.$apply();
    }
}

export const TestComponent = {
    templateUrl: './views/app/components/test/test.component.html',
    controller: TestController,
    controllerAs: 'vm',
    bindings: {}
}

Saya menemukan pekerjaan di sekitar saya percaya. http://stackoverflow.com/questions/38449126/how-to-set-up-ng-file-upload-in-laravel-angular-project/38486379#38486379

+1

@ntrp @guruward @coli @lgersman @jgoldber @Siyfion
Bagaimana Anda memperbaiki validasi untuk
Validasi saya:
this.catalougeForm = this.catalougeFormBuilder.group({
catalougeIconName: ['',Validator.diperlukan]
});
Html:
(ubah)="changeListener($event)">

Validator saya sedang mempertimbangkan nilai catalougeIconName sebagai kosong/null setelah saya mengunggah.
Gambar sedang dikirim, tetapi validator tidak berfungsi

Ada pembaruan tentang ini?

Ada pembaruan?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat