Angular 在触发更改时不更新 Ng 类

Angular not updating Ng-class when on-change is triggered

本文关键字:更新 Ng Angular      更新时间:2023-09-26
角度

有一个奇怪的问题。我可以通过 ng-click 让它工作,但出于其他原因我需要使用 onchange。

我的代码

似乎适用于可以按下以触发相同代码的其他按钮,但是当涉及到我的上传按钮时,它决定不更新ng类,即使scope.slideMenu实际上已注销为true。

我还想在用户完成选择图像/文件后关闭菜单,如果有人也可以提供帮助。

这是代码:

.HTML

                <div class="app-slide-menu"
                     ng-class="{'app-menu-active': slideMenu}">
                    <form class="app-set-image-file-form">
                        <label class="app-file-input"
                               title="Upload Image">
                            <i class="icon-enter"></i>
                            <input type="file"
                                   onchange="angular.element(this).scope().setImageFile(this)"
                                   accept="image/*">
                        </label>
                    </form>
                </div>

现在对于 JS:

        scope.setImageFile = function (element) {
        var reader = new FileReader();
        // Converts the image to a data URL.
        reader.readAsDataURL(element.files[0]);
        scope.slideMenuToggle();
        /**
         * When chosen image is selected it triggers the onload function to pass the image to the whiteboardService.
         * @param event - Saves the event of the input field to get the images data URL.
         */
        reader.onload = function (event) {
            fabric.Image.fromURL(event.target.result, function (img) {
                whiteboardService.uploadImageToCanvas(img);
            });
            // Resets the form that wraps round the file input to allow the
            // user to add more than one of the same file.
            // NOTE: This will break other inputs if you put them inside this form
            $('.app-set-image-file-form').trigger('reset');
        };
    };

和简单的切换 JS:

    scope.slideMenuToggle = function () {
        scope.slideMenu = !scope.slideMenu;
    };

使用 ngChange . onChange仍然是使用Angular之前的JavaScript onChange。当你使用onChange时,Angular并不知道事情已经发生了变化。

这是需要调用$scope.$apply()的罕见情况之一(使用 onChange 时)

我认为您最好的选择是为自定义 onchange 创建一个角度指令,如下所示:

app.directive('customOnChange', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var onChangeHandler = scope.$eval(attrs.customOnChange);
            element.bind('change', onChangeHandler);
        }
    };
});

然后,您可以在输入中像这样使用它: <input type="file" custom-on-change="setImageFile" accept="image/*">

最后,在控制器中,您可以执行以下操作:

$scope.setImageFile = function (element) {
    var reader = new FileReader();
    // Converts the image to a data URL.
    reader.readAsDataURL(element.files[0]);
    scope.slideMenuToggle();
    /**
     * When chosen image is selected it triggers the onload function to pass the image to the whiteboardService.
     * @param event - Saves the event of the input field to get the images data URL.
     */
    reader.onload = function (event) {
        fabric.Image.fromURL(event.target.result, function (img) {
            whiteboardService.uploadImageToCanvas(img);
        });
        // Resets the form that wraps round the file input to allow the
        // user to add more than one of the same file.
        // NOTE: This will break other inputs if you put them inside this form
        $('.app-set-image-file-form').trigger('reset');
    };
};

希望这能有所帮助。

好的伙计们,

很抱歉,您的建议对我没有帮助,但我设法找到了修复我的错误的解决方案,但我真的不明白为什么,所以如果您能让我知道,请告诉我。

我基本上在输入标签中添加了一类"js-input-file",然后将这段代码放在下面以触发范围重置。

        var inputScope = angular.element('.js-input-file').scope();
        inputScope.$apply();

这解决了我的问题,但我只是无法理解为什么要放置scope.$apply(); 本身并不能解决问题,但上述可以。让我知道你的想法。