设置 ngIf 的 Angular 指令 [英] Angular directive that sets ngIf

查看:22
本文介绍了设置 ngIf 的 Angular 指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一些 DOM 元素加载起来相当昂贵,因此我一直使用以下模式来确保它们在需要时才加载:

本质上,这确保元素仅在 someCondition 为真时才添加到 DOM 中,然后保持在那里.但是,那里有相当多的重复逻辑,因此我想将逻辑提取到指令中.

这是我的尝试:

导出函数 IfEverShown($parse: angular.IParseService): angular.IDirective {返回 {限制:A",编译:函数(元素:angular.IAugmentedJQuery,属性:angular.IAttributes) {如果(!属性[ngShow"]){返回;}element.attr("ng-if", "everShown");返回 {前:功能(范围:angular.IScope){范围["everShown"] = false;attributes.$observe('ngShow', function (expr) {范围.$watch(函数(){返回 $parse(<any> expr)(scope);}, 函数(值){如果(值){范围["everShown"] = true;}});});}};}};}

那么用法是:

然而,即使 DOM 中的 ng-if 值按预期更改,Angular 也会简单地忽略其上的更改:如果之前没有 ng-if,则该元素始终存在于 DOM 中,如果有以前的值,即使我改变它也总是能观察到.

我怎么能在这里得到想要的行为?我可以从指令修改 ngIf 吗?否则,是否有其他方法可以确保在 ng-show 条件至少为真一次之前元素不会被添加到 DOM 中?

谢谢!

解决方案

$编译服务不会自动编译在编译阶段添加到元素的指令.任何新添加的指令都需要在链接阶段手动编译:

app.directive("myIf", function($compile) {返回 {优先级:1000,终端:真的,编译:函数(tElem,tAttrs){tAttrs.$set("ngIf", tAttrs.myIf);tAttrs.$set("myIf", null);返回postLink;}}函数 postLink(scope, elem, attrs) {$compile(elem)(范围);}});

上面的示例演示了一个名为 my-if 的自定义指令.它在编译阶段添加了一个 ng-if 指令,并在链接阶段手动编译它.

请注意,它是作为高优先级的 "terminal" 指令实现的,并且它删除了 my-if 属性,以便指令仅编译一次.

PLNKR 演示.

I have a few DOM elements in my application that are fairly expensive to load, so I have been using the following pattern to ensure that they aren't loaded until needed:

<div ng-if="someCondition || everShown" ng-show="someCondition">

Essentially, that makes sure that the element is only added to the DOM once someCondition is true and then it remains there. However, there is a fair bit of repeated logic there and thus I wanted to extract the logic into a directive.

This has been my attempt:

export function IfEverShown($parse: angular.IParseService): angular.IDirective {    
    return {
        restrict: "A",
        compile: function(element: angular.IAugmentedJQuery,
                          attributes: angular.IAttributes) {
            if (!attributes["ngShow"]) {
                return;
            }
            element.attr("ng-if", "everShown");

            return {
                pre: function(scope: angular.IScope) {
                    scope["everShown"] = false;
                    attributes.$observe('ngShow', function (expr) {
                        scope.$watch(function () {
                            return $parse(<any> expr)(scope);
                        }, function (value) {
                            if (value) {
                                scope["everShown"] = true;
                            }
                        });
                    });
                }
            };
        }
    };
}

The usage would then be:

<div ng-show="someCondition" if-ever-shown>

However, even though the ng-if value in the DOM changes as expected, Angular simply ignores the changes on it: if there was no previous ng-if, the element is always present in the DOM, and if there was a previous value, it is always observed even after I change it.

How could I get the desired behavior here? Can I get to modify an ngIf from a directive? Otherwise, is there other way to ensure that the element doesn't get added to the DOM until the ng-show condition has been true at least once?

Thanks!

解决方案

The $compile service does not automatically compile directives added to the element during the compile phase. Any newly added directives need to be manually compiled in the link phase:

app.directive("myIf", function($compile) {
  return {
    priority: 1000,
    terminal: true,
    compile: function(tElem, tAttrs) {
      tAttrs.$set("ngIf", tAttrs.myIf);
      tAttrs.$set("myIf", null);
      return postLink;
    }
  }
  function postLink(scope, elem, attrs) {
    $compile(elem)(scope);
  }
});

The above example demonstrates a custom directive called my-if. It adds an ng-if directive during the compile phase and manually compiles it during the link phase.

Notice that it is implemented as a high priority "terminal" directive and that it removes the my-if attribute so that directives are compiled only once.

The DEMO on PLNKR.

这篇关于设置 ngIf 的 Angular 指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆