2017-10-18 57 views
0

我有一個指令wriiten角1,它支持將圖像拖放到Web應用程序中。migrate angular1指令到angular4

下面

是代碼:

'use strict'; 
angular.module('abc').directive("imageFileRead", ['$document', '$q', '$window', function ($document, $q, $window) { 

    var URL = $window.webkitURL || $window.URL; 

    //allowed extensions 
    var fileExtension = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/bmp']; 

    var isFileTypeAllowed = function (uploadedFile) { 
     try{ 
      return $.inArray(uploadedFile.type, fileExtension) == -1 ? false : true; 
     } 
     catch(Ex){ 

     } 
    }; 

    var getResizeArea = function() { 
     var resizeArea = document.createElement('canvas'); 
     resizeArea.id = 'result_image'; 
     resizeArea.style.visibility = 'hidden'; 
     document.body.appendChild(resizeArea); 
     return resizeArea; 
    }; 

    var resizeImage = function (origImage, options) { 
     var maxHeight = options.resizeMaxHeight; 
     var maxWidth = options.resizeMaxWidth; 
     var quality = options.resizeQuality; 
     var type = options.resizeType; 

     var canvas = getResizeArea(); 

     var height = origImage.height; 
     var width = origImage.width; 

     // calculate the width and height, constraining the proportions 
     if (width > height) { 
      if (width > maxWidth) { 
       height = Math.round(height *= maxWidth/width); 
       width = maxWidth; 
      } 
     } else { 
      if (height > maxHeight) { 
       width = Math.round(width *= maxHeight/height); 
       height = maxHeight; 
      } 
     } 

     canvas.width = width; 
     canvas.height = height; 

     //draw image on canvas 
     var ctx = canvas.getContext("2d"); 
     ctx.drawImage(origImage, 0, 0, width, height); 

     // get the data from canvas as 70% jpg (or specified type). 
     return canvas.toDataURL(type, quality); 
    }; 

    var createImage = function (url, callback) { 
     var image = new Image(); 
     image.onload = function() { 
      callback(image); 
     }; 
     image.src = url; 
    }; 

    var fileToDataURL = function (file) { 
     var deferred = $q.defer(); 
     var reader = new FileReader(); 
     reader.onload = function (e) { 
      deferred.resolve(e.target.result); 
     }; 
     reader.readAsDataURL(file); 
     return deferred.promise; 
    }; 

    return { 
     restrict: 'A', 
     scope: { 
      resizeMaxHeight: '@?', 
      resizeMaxWidth: '@?', 
      resizeQuality: '@?', 
      resizeType: '@?', 
      whenToCompress: '@?', 
      onImageDropCtrlFn: '&onImageDrop' 
     }, 
     link: function (scope, element, attrs, ctrl) { 

      scope.fileDetails = { fileData: {}, base64FileData: '', isValid: false }; 

      scope.options = { 
       resizeMaxHeight: parseInt(scope.resizeMaxHeight) || 300, 
       resizeMaxWidth: parseInt(scope.resizeMaxHeight) || 250, 
       resizeQuality: parseInt(scope.resizeMaxHeight) || 0.9, 
       resizeType: scope.resizeType || 'image/png' 
      }; 

      var doResizing = function (imageResult, callback) { 
       createImage(imageResult.url, function (image) { 
        var dataURL = resizeImage(image, scope.options); 
        imageResult.resized = { 
         dataURL: dataURL, 
         type: dataURL.match(/:(.+\/.+);/)[1], 
        }; 
        callback(imageResult); 
       }); 
      }; 

      var applyScope = function (isValidFile) { 
       scope.fileDetails.isValid = isValidFile; 
       scope.onImageDropCtrlFn({ fileDetails: scope.fileDetails }); 
      }; 

      var handleUserChooseAndDragEvents = function (fileDetails) { 
       scope.fileDetails.fileData = fileDetails; 
       if (isFileTypeAllowed(scope.fileDetails.fileData)) { 

        fileToDataURL(scope.fileDetails.fileData).then(function (dataURL) { 
         scope.fileDetails.base64FileData = dataURL; 
         if (scope.resizeMaxHeight || scope.resizeMaxWidth) { 
          //resize image 
          if ((scope.fileDetails.fileData.size/1000000) >= parseInt(scope.whenToCompress)) { 
           //do image compression 
           var imageResult = { 
            file: scope.fileDetails.fileData, 
            url: URL.createObjectURL(scope.fileDetails.fileData), 
            dataURL: scope.fileDetails.base64FileData 
           }; 

           doResizing(imageResult, function (imageResult) { 
            scope.fileDetails.fileData = imageResult.file; 
            scope.fileDetails.base64FileData = imageResult.resized.dataURL; 
            //scope.fileDetails.fileData.type = imageResult.resized.type; 
            applyScope(true); 
           }); 
          } else { 
           //no compresssion needed 
           applyScope(true); 
          } 
         } 
         else { 
          //no resizing 
          applyScope(true); 
         } 
        }); 
       } 
       else { 
        applyScope(false); 
       } 
      }; 

      //image choose event 
      element.bind("change", function (changeEvent) { 
       if (changeEvent.target.files) { 
        handleUserChooseAndDragEvents(changeEvent.target.files[0]); 
       } 
      }); 

      //image drag and drop 
      var onDragOver = function (e) { 
       e.preventDefault(); 
      }; 

      var onDragEnd = function (e) { 
       e.preventDefault(); 
      }; 

      $document.bind("dragover", onDragOver); 

      //Dragging ends on the overlay, which takes the whole window 
      element.bind("dragleave", onDragEnd) 
        .bind("drop", function (e) { 
         e.preventDefault(); 
         e.stopPropagation(); 
         handleUserChooseAndDragEvents(e.originalEvent.dataTransfer.files[0]); 
         onDragEnd(e); 
        }); 
     } 
    } 
}]); 

我試圖改變成角4

下面是角4碼:

import { Directive, ElementRef, Input, OnInit, Inject } from '@angular/core'; 
import { DOCUMENT } from '@angular/platform-browser'; 
declare var $: any; 

@Directive({ 
    selector: '[appImageFileRead]' 
}) 
export class ImageFileReadDirective implements OnInit { 
    @Input() resize_max_height: any; 
    @Input() resize_max_width: any; 
    @Input() resize_quality: any; 
    @Input() resize_type: any; 
    @Input() when_to_compress: any; 
    @Input() onImageDropCtrlFn: any = '&onImageDrop'; 
    currentElem: any; 
    URL: any = window.URL; 
    //allowed extensions 
    fileExtension: any = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/bmp']; 
    fileDetails: any = { fileData: {}, base64FileData: '', isValid: false }; 
    options: any; 

    constructor(@Inject(DOCUMENT) private document: any,el: ElementRef) { 
     this.currentElem = el; 

    } 

    ngOnInit() { 
     console.log("resize_max_height======" + this.resize_max_height); 
     this.options = { 
      resizeMaxHeight: parseInt(this.resize_max_width) || 300, 
      resizeMaxWidth: parseInt(this.resize_max_width) || 250, 
      resizeQuality: parseInt(this.resize_max_width) || 0.9, 
      resizeType: this.resize_type || 'image/png' 
     } 
     this.currentElem.bind("change", function (changeEvent: any) { 
      if (changeEvent.target.files) { 
       this.handleUserChooseAndDragEvents(changeEvent.target.files[0]); 
      } 
     }); 
     this.document.bind("dragover", this.onDragOver); 
     this.currentElem.bind("dragleave", this.onDragEnd) 
      .bind("drop", function (e: any) { 
       e.preventDefault(); 
       e.stopPropagation(); 
       this.handleUserChooseAndDragEvents(e.originalEvent.dataTransfer.files[0]); 
       this.onDragEnd(e); 
      }); 
    } 





    isFileTypeAllowed(uploadedFile: any) { 
     try { 
      return $.inArray(uploadedFile.type, this.fileExtension) == -1 ? false : true; 
     } 
     catch (Ex) { 

     } 
    } 

    getResizeArea() { 
     var resizeArea = document.createElement('canvas'); 
     resizeArea.id = 'result_image'; 
     resizeArea.style.visibility = 'hidden'; 
     document.body.appendChild(resizeArea); 
     return resizeArea; 
    } 

    resizeImage(origImage: any, options: any) { 
     var maxHeight = options.resizeMaxHeight; 
     var maxWidth = options.resizeMaxWidth; 
     var quality = options.resizeQuality; 
     var type = options.resizeType; 

     var canvas = this.getResizeArea(); 

     var height = origImage.height; 
     var width = origImage.width; 

     // calculate the width and height, constraining the proportions 
     if (width > height) { 
      if (width > maxWidth) { 
       height = Math.round(height *= maxWidth/width); 
       width = maxWidth; 
      } 
     } else { 
      if (height > maxHeight) { 
       width = Math.round(width *= maxHeight/height); 
       height = maxHeight; 
      } 
     } 

     canvas.width = width; 
     canvas.height = height; 

     //draw image on canvas 
     var ctx = canvas.getContext("2d"); 
     ctx.drawImage(origImage, 0, 0, width, height); 

     // get the data from canvas as 70% jpg (or specified type). 
     return canvas.toDataURL(type, quality); 
    } 

    createImage(url: any, callback: any) { 
     var image = new Image(); 
     image.onload = function() { 
      callback(image); 
     }; 
     image.src = url; 
    } 

    fileToDataURL(file: any) { 
     var deferred = new Promise((resolve, reject) => { 
      var reader = new FileReader(); 
      reader.onload = function (e: any) { 
       resolve(e.target.result); 
      }; 
      reader.readAsDataURL(file); 

     }).then(); 
     return deferred; 

    } 





    doResizing(imageResult: any, callback: any) { 
     this.createImage(imageResult.url, function (image: any) { 
      var dataURL = this.resizeImage(image, this.options); 
      imageResult.resized = { 
       dataURL: dataURL, 
       type: dataURL.match(/:(.+\/.+);/)[1], 
      }; 
      callback(imageResult); 
     }); 
    } 

    applyScope(isValidFile: any) { 
     this.fileDetails.isValid = isValidFile; 
     this.onImageDropCtrlFn({ fileDetails: this.fileDetails }); 
    }; 

    handleUserChooseAndDragEvents(fileDetails: any) { 
     this.fileDetails.fileData = fileDetails; 
     if (this.isFileTypeAllowed(this.fileDetails.fileData)) { 

      this.fileToDataURL(this.fileDetails.fileData).then(function (dataURL: any) { 
       this.fileDetails.base64FileData = dataURL; 
       if (this.resize_max_height || this.resize_max_width) { 
        //resize image 
        if ((this.fileDetails.fileData.size/1000000) >= parseInt(this.whenToCompress)) { 
         //do image compression 
         var imageResult = { 
          file: this.fileDetails.fileData, 
          url: URL.createObjectURL(this.fileDetails.fileData), 
          dataURL: this.fileDetails.base64FileData 
         }; 

         this.doResizing(imageResult, function (imageResult: any) { 
          this.fileDetails.fileData = imageResult.file; 
          this.fileDetails.base64FileData = imageResult.resized.dataURL; 
          //scope.fileDetails.fileData.type = imageResult.resized.type; 
          this.applyScope(true); 
         }); 
        } else { 
         //no compresssion needed 
         this.applyScope(true); 
        } 
       } 
       else { 
        //no resizing 
        this.applyScope(true); 
       } 
      }); 
     } 
     else { 
      this.applyScope(false); 
     } 
    } 

//image choose event 


//image drag and drop 
onDragOver(e:any) { 
    e.preventDefault(); 
} 

onDragEnd(e:any) { 
    e.preventDefault(); 
} 



//Dragging ends on the overlay, which takes the whole window 


} 

我不知道這.currentElem.bind 和this.document.bind(「dragover」,this.onDragOver);

如何實現或綁定元素上的事件。

我也需要一些關於承諾的指導,如果它的執行是否正確。

<div class="form-group text-area" 
         id="file-drop" 
         image-file-read 
         on-image-drop="imageDropped(fileDetails)" 
         resize-max-height="300" 
         resize-max-width="300" 
         resize-quality="0.9" 
         resize-type="image/png" 
         when-to-compress="3"> 

謝謝!!

編輯:試圖增加HostListener

@HostListener('document:dragover') onDocumentDragOver(evt: any) { 
     evt.preventDefault(); 
     evt.stopPropagation(); 
     this.background = '#999'; 
     this.onDragOver(evt); 
    } 

,但是這給錯誤

無法讀取的不確定

回答

1

財產 '的preventDefault' 要綁定到的屬性元素,你可以@HostBinding。綁定到元素的事件,你可以使用@HostListener

@HostBinding('class.test-class') hasTestClass = false; 

@HostListener('mouseenter') onMouseEnter() { 
    // ... 
} 

下面是更多關於這個話題:https://alligator.io/angular/hostbinding-hostlistener/

您也可以使用這個結合windowdocument事件,就像這樣:

@HostListener('document:dragover', ['$event']) 
onDocumentDragOver(e) { 
    // ... 
} 

關於承諾 - 你正在創造承諾,然後打電話給.then() - 這將立即運行它,這可能不是你想要的...也沒有必要承諾保存到deferred變量,然後返回它,簡單地返回new Promise,就像這樣:

fileToDataURL(file: any) { 
    return new Promise((resolve, reject) => { 
     var reader = new FileReader(); 
     reader.onload = function (e: any) { 
      resolve(e.target.result); 
     }; 
     reader.readAsDataURL(file); 
    }); 
} 
+0

感謝@馬丁:但是我想通過事件HostListener.How我可以做that.Please看到更新的問題。 –

+0

您需要使用HostListener裝飾器的第二個參數,請參閱我更新的答案 –