将angular1指令迁移到angular4

时间:2017-10-18 11:41:30

标签: angularjs angular directive

我有一个角度为1的指令,它支持将图像拖放到网络应用程序中。

下面是代码:

'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


}

我不确定this.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);
    }

但是这给出了错误

  

无法读取未定义

的属性'preventDefault'

1 个答案:

答案 0 :(得分:1)

要绑定到元素的属性,您可以@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() - 这将立即运行它,这可能不是您想要的...也没有必要将承诺保存到{{ 1}}变量然后返回它,只需返回deferred,如下所示:

new Promise