【问题标题】:How to pass a function through a directive attribute while keeping the original 'this' reference如何在保留原始“this”引用的同时通过指令属性传递函数
【发布时间】:2016-09-30 04:42:55
【问题描述】:

我开发了一个用于在 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

【问题讨论】:

    标签: angularjs angularjs-directive angular-directive


    【解决方案1】:

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

    通过调用一个返回绑定到“本地” this 的函数的函数,我能够在指令中保留正确的引用。

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

    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">
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      • 2010-09-18
      • 2011-05-18
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多