简体   繁体   English

将angular1指令迁移到angular4

[英]migrate angular1 directive to angular4

i have a directive wriiten in angular 1.which supports drag and drop of images into the web app. 我有一个角度为1的指令wriiten,它支持将图像拖放到Web应用程序中。

below is the code: 下面是代码:

'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);
                   });
        }
    }
}]);

I'm trying to change into angular 4 我正在尝试更改为角度4

Below is the angular 4 code: 以下是角度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


}

I'm not sure about this.currentElem.bind and this.document.bind("dragover", this.onDragOver); 我不确定this.currentElem.bind和this.document.bind(“ dragover”,this.onDragOver);

how to implement or bind events on the element. 如何在元素上实现或绑定事件。

I also need some guidance on the promise if its implemented correctly or not. 如果诺言正确执行,我还需要一些指导。

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

Thanks!! 谢谢!!

EDIT:Trying to add HostListener 编辑:尝试添加HostListener

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

but this gives and error 但这给和错误

Cannot read property 'preventDefault' of undefined 无法读取未定义的属性“ preventDefault”

To bind to properties of the element, you can you @HostBinding . 要绑定到元素的属性,可以@HostBinding To bind to events of the element, you can use @HostListener : 要绑定到元素的事件,可以使用@HostListener

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

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

Here is more about this topic: https://alligator.io/angular/hostbinding-hostlistener/ 这是有关此主题的更多信息: https : //alligator.io/angular/hostbinding-hostlistener/

You can also use this for binding to window or document events, like this: 您还可以使用它来绑定windowdocument事件,如下所示:

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

About the promise - you are creating the promise and then calling .then() on it - this will immediately run it, that's not probably what you want... Also there is no need to save the promise to deferred variable and then return it, simply return the new Promise , like this: 关于promise-您正在创建promise,然后在其上调用.then() -这将立即运行它,这可能不是您想要的...而且也无需将promise保存为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);
    });
}

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

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