当前位置: 首页 > 面试题库 >

在指令链接功能中动态添加ng-click

壤驷阳冰
2023-03-14
问题内容

我正在尝试创建一条指令,该指令允许将元素定义为可点击或不可点击,并且将被定义为:

<page is-clickable="true">
    transcluded elements...
</page>

我希望生成的HTML是:

<page is-clickable="true" ng-click="onHandleClick()">
    transcluded elements...
</page>

我的指令实现如下所示:

app.directive('page', function() {
    return {
        restrict: 'E',
        template: '<div ng-transclude></div>',
        transclude: true,
        link: function(scope, element, attrs) {
            var isClickable = angular.isDefined(attrs.isClickable) && scope.$eval(attrs.isClickable) === true ? true : false;

            if (isClickable) {
                attrs.$set('ngClick', 'onHandleClick()');
            }

            scope.onHandleClick = function() {
                console.log('onHandleClick');
            };
        }
    };
});

我可以看到,添加新属性后,Angular不了解ng- click,因此不会触发。我尝试$compile在设置属性后添加一个,但它会导致无限的链接/编译循环

我知道我可以只检查onHandleClick()函数中的isClickable值是否为true,但是我很好奇如何动态添加ng- click事件来执行此操作,因为我可能需要使用多个其他ng-*指令来执行此操作,而我不想这样做添加不必要的开销。有任何想法吗?


问题答案:

更好的解决方案(新):

阅读了Angular文档后,我发现了这一点:

您可以将template指定为表示模板的字符串,或者指定为使用两个参数tElement和tAttrs(在下面的编译函数api中进行描述)并返回表示模板的字符串值的函数。

因此,我的新指令如下所示:(我相信这是处理此类问题的适当“角度”方式)

app.directive('page', function() {
    return {
        restrict: 'E',
        replace: true,
        template: function(tElement, tAttrs) {
            var isClickable = angular.isDefined(tAttrs.isClickable) && eval(tAttrs.isClickable) === true ? true : false;

            var clickAttr = isClickable ? 'ng-click="onHandleClick()"' : '';

            return '<div ' + clickAttr + ' ng-transclude></div>';
        },
        transclude: true,
        link: function(scope, element, attrs) {
            scope.onHandleClick = function() {
                console.log('onHandleClick');
            };
        }
    };
});

注意新的模板功能。现在,我正在编译该函数之前的模板。

替代解决方案(旧):

添加replace: true该函数可消除重新编译指令时的无限循环问题。然后在链接函数中,我只是在添加新属性后重新编译元素。不过要注意一件事,因为我ng- transclude在元素上有一条指令,所以我需要删除该指令,以便它不会尝试在第二次编译中包含任何内容,因为没有要包含的内容。

这是我的指令现在的样子:

app.directive('page', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div ng-transclude></div>',
        transclude: true,
        link: function(scope, element, attrs) {
            var isClickable = angular.isDefined(attrs.isClickable) && scope.$eval(attrs.isClickable) === true ? true : false;

            if (isClickable) {
                attrs.$set('ngClick', 'onHandleClick()');
                element.removeAttr('ng-transclude');
                $compile(element)(scope);
            }

            scope.onHandleClick = function() {
                console.log('onHandleClick');
            };
        }
    };
});

我认为第二次重新编译模板并不是理想的选择,因此我觉得在第一次编译模板之前仍然有一种方法可以这样做。



 类似资料:
  • 问题内容: 我正在尝试在ng-repeat中动态添加不同的指令,但是输出没有被解释为指令。 我在这里添加了一个简单的示例:http : //plnkr.co/edit/6pREpoqvmcnJJWzhZZKq 控制器: 指示: HTML: 如何通过ng-repeat 使角度拾取在中指定的指令? 问题答案: 我知道这是一个老问题,但是google将我带到了这里,但我不喜欢这里的答案。所以我创建了这个

  • 问题内容: 我正在做的事情非常精简,可以解决问题。 我有一个简单的。每当您单击一个元素时,它都会添加另一个元素。但是,需要先对其进行编译才能正确呈现。 我的研究使我走向了。但是所有示例都使用了一个复杂的结构,我真的不知道如何在这里应用它。 小提琴在这里:http : //jsfiddle.net/paulocoelho/fBjbP/1/ JS在这里: Josh David Miller的解决方案:

  • 问题内容: 也许我对指令控制器的工作原理有一个基本的误解,据我了解,它们被用作暴露给其他指令和控制器的一种API。我正在尝试使控制器和链接功能进行内部通信。 例如,我希望能够通过控制器函数设置一个变量,然后在链接函数中使用它: 如何在链接功能中访问myVar或sayHi?还是我完全错过了重点? 问题答案: 控制器的$ scope(在控制器中定义,而不在函数中定义)和链接都相同。可以从链接中使用在控

  • 问题内容: 在我的某些指令中,我正在向作用域添加函数以处理特定于该指令的逻辑。例如: 我该如何测试该功能?我到处搜索如何测试指令,但是发现的更多内容是测试元素上的更改。我当然可以在每次测试之前编译指令,但是每次都会覆盖我的范围。我想在我的范围更改属性时测试该功能。 有什么方法可以保留从指令定义返回的对象吗?然后,我可以直接调用链接函数并测试作用域上定义的每个函数的行为。有没有更好的方法来完成所有这

  • 本文向大家介绍Angularjs 实现动态添加控件功能,包括了Angularjs 实现动态添加控件功能的使用技巧和注意事项,需要的朋友参考一下 实现下面这样的需求: 点击增加一块数据盘,会出现数据盘选项。 (1)最开始,想到原生JavaScript,jQuery (appendChild()等方法结合AngularJS来添加新的元素。但是突然发现控件里面的数据绑定,原生javascript没法控制

  • 问题内容: 我花了一段时间试图找到一个优雅的解决方案,而我却找到了一个“可行”的解决方案,它感觉不是最简单或正确的做事方式。 所以,我的问题是…如何动态加载指令!在某些情况下,以下是我希望我能摆脱它的方式!除了模板加载之外,我没有包含路由或其他任何内容,而是为下面的控制器分配了ng- controller。 app.js template.html 任何人都可以提供的建议将不胜感激,如果我做任何明