向AngularJS转换内容

时间:2015-11-20 01:15:37

标签: javascript html angularjs angularjs-directive angularjs-ng-transclude

将事件处理程序添加到翻译内容的正确方法是什么?我不希望我的指令的使用者将他们自己的点击处理程序添加到文档中。该指令应该处理它。但我不确定如何正确地将处理程序添加到通过ng-transclude传递的内容中。

小提问:https://jsfiddle.net/hoe71p0e/12/ (无法让Angular.js和JSFiddle工作;我的链接功能没有被调用)

foo.html

<my-foo>
    <button type="button">Foo</button>
</my-foo>

foo.js

return {
    template: "<div class='my-foo' data-ng-transclude></div>"
    link: function($scope, $elem, $attrs, $ctrl, $transclude) {
        $scope.foo = function() {
            console.log("this is never called");
        };

        $transclude(function(clone) {
            for (var i in clone) {
                if (clone[i].localName === "button") {
                    angular.element(clone[i]).attr("data-ng-click", "foo()");
                }
            }
        });
    }
};

预期结果(点击按钮应调用foo)

<div class="my-foo">
    <button type="button" data-ng-click="foo()">Foo</button>
</div>

实际结果(点击按钮不执行任何操作)

<div class="my-foo">
    <button type="button">Foo</button>
</div>

请注意,该按钮上的data-ng-click属性缺失。

另外,我已经看过几个像这样的例子......

broken.js

$transclude(function(clone) {
    angular.element(clone).find("button");
});

...但是那些失败是因为.find()没有带回结果,即使检查员似乎认为克隆包含一个&#34;按钮&#34;。

1 个答案:

答案 0 :(得分:2)

我无法想象你甚至在这个指令中链接。在你的小提琴中,你缺少一些基本要求,例如:元素样式指令中的ng-app=""restrict: 'E'(1.2.x必需)和transclude: true。通过这些修复,我们得到了一个有效的例子。此外,我不确定你要对$transclude(function(clone) { /*...*/做什么,但我怀疑这是不必要的。 请注意以下内容......

<my-foo>
    <button type="button" ng-click="foo()">Foo</button>
</my-foo>
.directive('myFoo', function() {
    return {
        transclude: true,
        restrict: 'E',
        template: '<div class="my-foo" ng-transclude></div>',
        link: function($scope, elem, attrs) {
            $scope.foo = function() {
                console.log('this is called!');
            };
        }
    };
});

JSFiddle Link - 工作演示

根据对话,您可以采取的最直接的方法是利用$compile服务并修改指令<button>link(一旦选定)元素的属性。注入$compile并观察以下内容......

.directive('myFoo', function($compile) {
    return {
        transclude: true,
        restrict: 'E',
        template: '<div class="my-foo" ng-transclude></div>',
        link: function($scope, elem, attrs) {

            $scope.foo = function() {
                console.log('called')
            }

            var button = elem.find('button');
            button.attr('ng-click', 'foo()');
            $compile(button)($scope);
        }
    };
});

JSFiddle Link - $compile演示