如何通过指令属性传递函数,同时保持原始'这个'参考

时间:2016-09-29 20:19:52

标签: angularjs angularjs-directive angular-directive

我已经在Angular中开发了一个文件上传指令。我想将成功回调从父组件传递给指令,但它在该函数中引用this,并且在此过程中会丢失。

在这种情况下我如何.bind(this)

父组件模板:

<input
   type="file"
   name="xml-file"
   class="hidden"
   id="xml-file-input"
   accept="text/xml"
   file-upload
   file-upload-accept="text/xml"
   file-upload-then="$ctrl.fileUploadOnSuccess"
   file-upload-url="/versementPublique/{{ $ctrl.noDemande }}/dossiers">

文件上传指令:

function FileUploadDirective(dialogBoxService, glossaryFilter, $parse, fileUploadService) {
  return {
    restrict: 'A',
    link(scope, elem, attrs) {
      const name = attrs.name;
      const url = attrs.fileUploadUrl;
      const type = attrs.fileUploadAccept;
      const successCallback = $parse(attrs.fileUploadThen)(scope);

      elem.on('change.upload', validate);

      function validate($event) {
        const errors = validateFile($event.target.files[0]);
        const isValid = errors.length === 0;

        if (!isValid) {
          dialogBoxService.open({
            title: glossaryFilter('erreur'),
            message: `
              Please correct the following:
              <ul class="list list--bullet">
                ${errors.map(err => `<li>${err}</li>`)}
              </ul>
            `,
          });
          scope.$apply();
          resetFileInput();
        } else {   
          const file = $event.target.files[0];
          const fd = new FormData();

          fd.append(name, file);

          this.coreService.http({
            method: 'POST',
            url: url,
            data: fd,
            transformRequest: angular.identity,
            headers: {
              'Content-Type': undefined,
            },
          })
          .then(then, catcher, notify);
        }
      }

      ...

      function then(response) {
        resetFileInput();
        successCallback();
      }

      function catcher(err) {
        console.error(err);
        resetFileInput();
      }

      function notify(event) {
        console.log(event);
      }

      function resetFileInput() {
        elem
          .off('change.upload')
          .val('')
          .on('change.upload', fileUploadService.uploadFile);
      }
    },
  };
}

传递给属性的函数:

class ParentComponent {
  constructor($rootScope) {
     this.$rootScope = $rootScope;
  }

  // Because there is a `this` in here, when it is called in the
  // directive, it is lost. There is no way to .bind() in the
  // template, so I'm lost as how to keep the right `this`.
  fileUploadOnSuccess() {
    this.$rootScope.$broadcast('updateDossier');
  }
}

ParentComponent.$inject = ['$rootScope'];

控制台出错:

因为this始终是调用函数的函数(除非你.bind()),所以它无法在定义函数的类中找到属性$rootScope

我已尝试在模板中绑定this,但它不起作用。

我怎么能这样做?

gouvernementales.js:5328 Uncaught TypeError: Cannot read property '$rootScope' of undefined

1 个答案:

答案 0 :(得分:0)

好的,这就是我解决this问题的方法:

通过调用一个返回绑定到&#34; local&#34;的函数的函数。这一点,我能够在指令内部保留正确的引用。

通过属性传递给指令的成功回调:

fileUploadOnSuccess() {
    return function success() {
      this.$rootScope.$broadcast('updateDossier');
    }.bind(this);
  }

模板:

<input
    type="file"
    name="fileDossiers"
    class="hidden"
    id="xml-file-input"
    accept="text/xml"
    file-upload
    file-upload-accept="text/xml"
    file-upload-then="$ctrl.fileUploadOnSuccess()"
    file-upload-url="/versementPublique/dossiers">