简体   繁体   English

AngularJS Directive事件监听器在所有实例上触发

[英]AngularJS Directive event listener fires on all instances

I created a directive os-image-uploader to upload images then edit them and upload them to my server. 我创建了一个指令os-image-uploader来上传图像,然后对其进行编辑并将其上传到我的服务器。

Here's the template: 这是模板:

<label for="image_upload" class="image-upload-button"><span>Choose an image</span></label>
<input type="file" name="image_upload" id="image_upload" accept=".gif, .jpg, .png">

<image-editor id="image" ng-if="image.imageData.length > 0" image="{{image.imageData}}" selection-width="{{selectionWidth}}" selection-height="{{selectionHeight}}" width="{{width}}" height="{{height}}" controls="osImage.controls" state="image.state"></image-editor>

(the image editor is a nested directive which isn't causing any problems that I can tell) (图像编辑器是一个嵌套指令,不会引起我可以告诉的任何问题)

and here's my directive: 这是我的指令:

(function(angular) {
  'use strict';

  angular
    .module('AwareClientApp')
    .directive('osImageUploader', function() {
      return {
        restrict: 'E',
        templateUrl: 'scripts/components/os-image-uploader/os-image-uploader.html',
        scope: {
          selectionHeight: '@',
          selectionWidth: '@',
          width: '@',
          height: '@',
          url: '@',
          imageId: '@',
          type: '@',
          image: '='
        },
        controllerAs: 'osImage',
        controller: imageUploaderController,
        link: function(scope, element) {
          var input = element.find('#image_upload');
          element.on('click', function (e) {
            console.log(e);
            console.log('clicked');
            console.log(scope);
            console.log(element);
          });
           function readFile = () {
            if (scope.input[0].files && scope.input[0].files[0]) {
              var filereader = new FileReader();
              filereader.onload = function(e) {
                scope.image.imageData = e.target.result;
                scope.$root.$apply();
              };
              filereader.readAsDataURL(scope.input[0].files[0]);
            }
          }

          input.addEventListener('change', readFile);
        }
      };
    });

I have a link function that attaches an event listener to the file input in the directive. 我有一个链接函数,它将事件侦听器附加到指令中输入的文件。

It's been working great while I've been building it and testing it when I only have one instance of it in the html: 当我一直在构建它并在html中只有一个实例时对其进行测试时,它一直工作得很好:

<md-content class="md-padding input-tab-content images-edit" ng-if="!tabImages.isDisabled">
        <div class="header">
            <h1>Header</h1>
            <div layout="row" layout-sm="column" layout-align="space-around" ng-if="tabImages.loadingHeaderImage">
                <md-progress-circular class="md-primary" md-diameter="60px" md-mode='indeterminate'>
                </md-progress-circular>
            </div>
            <div class="header-image-container">
                <img ng-src="{{tabImages.images.header.url}}" style="top: {{tabImages.images.header.newCrop.top}}px; left: {{tabImages.images.header.newCrop.left}}px; width: {{tabImages.images.header.newCrop.width}}px;" alt="header-image" class="header-image"/>
            </div>
            <h4>header url: {{tabImages.images.header.url}}</h4>

            <os-image-uploader selection-width="400" selection-height="196" width="400" height="196" image-id="{{tabImages.images.header.id}}" type="header" image="tabImages.imageReference.header" input="tabImages.imageReference.header.input"></os-image-uploader>

        </div>
    </md-content>

However, I needed to add another section for a logo image on the same page. 但是,我需要在同一页面上为徽标图像添加另一部分。 So I did that: 所以我做到了:

<md-content class="md-padding input-tab-content images-edit" ng-if="!tabImages.isDisabled">
        <div class="logo">
            <h1>Logo</h1>
            <div layout="row" layout-sm="column" layout-align="space-around" ng-if="tabImages.loadingLogoImage">
                <md-progress-circular class="md-primary" md-diameter="60px" md-mode='indeterminate'>
                </md-progress-circular>
            </div>
            <div class="logo-image-container">
                <img ng-src="{{tabImages.images.logo.url}}" style="" alt="logo-image" class="logo-image"/>
            </div>
            <h4>logo url: {{tabImages.images.logo.url}}</h4>

            <os-image-uploader selection-width="400" selection-height="88" width="400" height="88" image-id="{{tabImages.images.logo.id}}" type="logo" image="tabImages.imageReference.logo" input="tabImages.imageReference.logo.input"></os-image-uploader>

        </div>

        <div class="header">
            <h1>Header</h1>
            <div layout="row" layout-sm="column" layout-align="space-around" ng-if="tabImages.loadingHeaderImage">
                <md-progress-circular class="md-primary" md-diameter="60px" md-mode='indeterminate'>
                </md-progress-circular>
            </div>
            <div class="header-image-container">
                <img ng-src="{{tabImages.images.header.url}}" style="top: {{tabImages.images.header.newCrop.top}}px; left: {{tabImages.images.header.newCrop.left}}px; width: {{tabImages.images.header.newCrop.width}}px;" alt="header-image" class="header-image"/>
            </div>
            <h4>header url: {{tabImages.images.header.url}}</h4>

            <os-image-uploader selection-width="400" selection-height="196" width="400" height="196" image-id="{{tabImages.images.header.id}}" type="header" image="tabImages.imageReference.header" input="tabImages.imageReference.header.input"></os-image-uploader>

        </div>
    </md-content>

The problem is that the click event (that I have been using to test this) and, more importantly, the change event are fired on both elements even though they have separate scopes and the elements that the event are bound to are in their respective directives. 问题在于,即使两个事件具有单独的作用域,并且绑定到该事件的元素都在各自的指令中,我还是一直使用click事件(我一直在对其进行测试),更重要的是,change事件在这两个元素上均被触发。

Console log for this click event (not sure how much it helps): 此Click事件的控制台日志(不确定其帮助程度):

os-image-uploader.js:46 j…y.Event {originalEvent: MouseEvent, type: "click", timeStamp: 8562.660000000002, jQuery2240034688928910062033: true, toElement: label.image-upload-button…}
os-image-uploader.js:49 clicked
os-image-uploader.js:50 Scope {$id: 837, $$childTail: null, $$childHead: null, $$prevSibling: Scope, $$nextSibling: null…}
os-image-uploader.js:51 [os-image-uploader.ng-isolate-scope, context: os-image-uploader.ng-isolate-scope]
os-image-uploader.js:46 j…y.Event {originalEvent: MouseEvent, type: "click", timeStamp: 8562.660000000002, jQuery2240034688928910062033: true, toElement: input#image_upload…}
os-image-uploader.js:49 clicked
os-image-uploader.js:50 Scope {$id: 836, $$childTail: null, $$childHead: null, $$prevSibling: null, $$nextSibling: Scope…}
os-image-uploader.js:51 [os-image-uploader.ng-isolate-scope, context: os-image-uploader.ng-isolate-scope]

What am I doing wrong here? 我在这里做错了什么? I've been working for days on this and I really hope it's not something stupid that I've missed. 我已经为此工作了好几天,我真的希望这不是我错过的愚蠢之举。

You end up having two inputs with the same id="image_upload" in the DOM tree while id is supposed to be unique in the entire document. 您最终在DOM树中拥有两个具有相同id="image_upload"输入,而id在整个文档中应该是唯一的。 I think this is the root cause of your problems. 我认为这是您遇到问题的根本原因。 It's better to use classes instead (or other attributes). 最好改用类(或其他属性)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM