【问题标题】:How to trigger $destroy event of already removed element scope?如何触发已删除元素范围的 $destroy 事件?
【发布时间】:2015-07-07 09:42:55
【问题描述】:

考虑以下指令:

class HasPermissionDirective {
    constructor(PermissionService) {
        this.restrict = 'A';
        this.priority = 1005;

        this.PermissionService = PermissionService;
    }

    compile(element, attrs) {
        let permission = _.trim(attrs.hasPermission),
            hide       = _.get(attrs, 'hideOnly'),
            $element   = angular.element(element);

        if (permission && !this.PermissionService.hasPermission(permission)) {
            if (!_.isUndefined(hide)) {
                hide = _.trim(hide);

                if (hide === 'visibility') {
                    $element.css('visibility', 'hidden');
                } else {
                    $element.hide();
                }
            } else {
                $element.remove();
            }
        }
    }

    link($scope, $element, attrs, ctrl) {
        $scope.$destroy();
    }
}

HasPermissionDirective.$inject = ['PermissionService'];

现在的问题是,$scope.$destroy() 总是执行,对于指令附加到的每个元素范围(当然)。

当我现在添加一个“isRemoved”成员变量并将其设置为 true 以防元素被删除并在链接函数中执行以下操作时:

if (this.isRemoved) {
    $scope.$destroy();
}

当然,只要删除了至少一个元素,就会为每个元素范围触发 $scope.$destroy(),因为该指令被处理为单例而不是实例。

我无法向元素节点添加任何信息,因为它似乎在编译后被删除并且只是一个注释节点“ngInclude:undefined”(不,我不删除节点,我添加了一个数据属性并想要在链接函数中获取它:$element.data('remove', true) 然后想要 $destroy 和 remove())。编辑:这似乎是 ngInclude-directive 的 transclude-behavior。

如果我从链接函数中删除 $scope.$destroy() 并仅删除节点,则 ngInclude 指令仍在运行...

我想要什么?我只想在编译时从 DOM 中删除元素,因为当前用户无权查看此元素/指令/视图,并且我还想避免进一步处理指令(在我的情况下,ng-include 不应该是不必要的请求模板(因为我们的服务器无论如何都会响应 401)等等)。

更新:我想我需要一种方法来设置编译函数内部的terminal 选项以停止处理即将到来的指令。我的问题是,即使之前删除了该元素,ngInclude 仍在运行。

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    找到解决方案!我还必须使用嵌入(在我检查 ngIf 的 impl 之后很明显)并且它只能在(前/后)链接函数内部使用,所以这里是 impl。对于遇到类似问题的人:

    class HasPermissionDirective {
        constructor(PermissionService) {
            this.restrict = 'A';
            this.priority = 1011; // high prio so the element is removed before all other directives can be processed
            this.transclude = 'element';
            this.$$tlb = true; // BAD! But w/o, transclusion for different directives won't work :(
    
            this.PermissionService = PermissionService;
        }
    
        preLink($scope, $element, attrs, ctrl, $transclude) {
            let $newScope = $scope.$new(),
                hide = _.get(attrs, 'hideOnly');
    
            $transclude($newScope, ($clone) => {
                if (!this.PermissionService.hasPermission(_.trim(attrs.hasPermission))) {
                    if (!_.isUndefined(hide)) {
                        hide = _.trim(hide);
    
                        if (hide === 'visibility') {
                            $clone.css('visibility', 'hidden');
                        } else {
                            $clone.hide();
                        }
                    } else {
                        $newScope.$destroy();
                        $newScope = null;
    
                        $clone.remove();
                        $clone = null;
                    }
                } else {
                    // in case the user has the permission we have to attach the element to the DOM (cause of transclusion)
                    $element.after($clone);
                }
            });
        }
    }
    
    HasPermissionDirective.$inject = ['PermissionService'];
    

    我也确实将实现外包给了控制器,这样我就可以重用逻辑,但我不想提供一个完整的例子来说明:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      相关资源
      最近更新 更多