Saya membuat pembungkus direktif sederhana di sekitar input file HTML untuk membuat pengikatan sudut berfungsi. Inilah arahan saya:

angular.module('myApp').directive('inputFile', InputFileDirective);

function InputFileDirective() {
  var bindings = {
    selectLabel: '@',
  };
  return {
    restrict: 'E',
    require: ['inputFile', 'ngModel'],
    scope: true,
    controllerAs: 'inputFileCtrl',
    bindToController: bindings,
    controller: function () {
    },
    template: `<input class="ng-hide" id="input-file-id" type="file" />
<label for="input-file-id" class="md-button md-raised md-primary">{{ inputFileCtrl.getButtonLabel() }}</label>`,
    link: link
  };

  function link(scope, element, attrs, controllers) {
    if (angular.isDefined(attrs.multiple)) {
      element.find('input').attr('multiple', 'multiple');
    }
    var inputFileCtrl = controllers[0];
    var ngModelCtrl = controllers[1];

    inputFileCtrl.getButtonLabel = function () {
      if (ngModelCtrl.$viewValue == undefined || ngModelCtrl.$viewValue.length == 0) {
        return inputFileCtrl.selectLabel;
      }
      else {
        return ngModelCtrl.$viewValue.length + (ngModelCtrl.$viewValue.length == 1 ? " file" : " files") + " selected";
      }
    };

    element.on('change', function (evt) {
      ngModelCtrl.$setViewValue(element.find('input')[0].files);
      ngModelCtrl.$render();
    });
  }
};

Dan inilah HTMLnya

<body ng-app="myApp" ng-controller="MyController as ctrl">
  <form name="ctrl.myForm">
    <input-file select-label="Select Attachment" ng-model="ctrl.attachment1"></input-file>

    <input-file select-label="Select Attachment" ng-model="ctrl.attachment2"></input-file>
  </form>
</body>

Ini cukup sederhana dan berfungsi - jika hanya satu yang ada di halaman. Segera setelah saya menambahkan yang kedua, saya perhatikan bahwa hanya yang pertama yang diperbarui. Jika saya memilih file dengan yang kedua, label akan diperbarui pada yang pertama. Kecurigaan saya adalah bahwa require ['inputFile'] menarik pengontrol untuk contoh direktif pertama ke dalam fungsi tautan atau sesuatu (yang seharusnya tidak terjadi). Bahkan sekarang saat saya mengetik ini, itu tidak masuk akal bagi saya. Jadi apa yang terjadi di sini dan bagaimana cara memperbaikinya?

Ini codepen untuk kalian mainkan dan coba cari tahu: http://codepen.io/astynax777 /pen/PzzBRv

1
Zach 16 Juni 2016, 20:48
Beginilah cara Anda mengikat menggunakan sintaks controllerAs. scope: true mengaktifkan ruang lingkup isolasi dan binding Anda dapat diikat ke properti bindToController. Saya memotong pena dan melakukannya dengan cara lain di sini: codepen.io/astynax777/pen/zBBLVR dan saya masih memiliki masalah ini. Juga, saya tidak menggunakan angular.element tetapi element yang diteruskan dari fungsi link (ini adalah tag <input-file>).
 – 
Zach
16 Juni 2016, 21:10
Saya harus mengoreksi diri sendiri seperti yang ditunjukkan Claies dan menyatakan bahwa scope: true membuat cakupan yang "secara prototipikal mewarisi dari cakupan induknya" seperti yang dinyatakan di sini: github.com/angular/angular.js/wiki/Understanding-Scopes
 – 
Zach
16 Juni 2016, 21:22

1 menjawab

Jawaban Terbaik

Masalah Anda bukan dengan sudut Anda ... ada pada html Anda. Anda menetapkan id yang sama dua kali. Ubah template Anda menjadi ini:

template: `<label class="md-button md-raised md-primary">{{ inputFileCtrl.getButtonLabel() }}<input class="ng-hide" type="file" /></label>`
1
Manatax 16 Juni 2016, 21:13
1
Kamu benar! Saya memang memiliki konflik id. Itu memecahkan masalah saya! Anda da Manatax!
 – 
Zach
16 Juni 2016, 21:18