我需要构建一个转换指令,将自定义指令转换为html。
<link text="hello world"></link>
<a class="someclass" ng-click="linkClicked('hello world')"></a>
linkClicked 。
如果我是负责持有'link'指令的html(使用隔离范围),那将是非常容易的,但我不是。这是一个 as-is 输入,我必须想办法继续这样做。
有很多关于如何使用指令的默认范围进行类似绑定的示例,但是我使用带控制器的John Papa's建议来编写我的控制器,但是不想在控制器上创建另一个实例在指令中。
这是我到目前为止所做的事情:
(function () {
'use strict';
angular
.module('app')
.directive('link', link);
link.$inject = ['$compile'];
function link($compile) {
return {
restrict: 'E',
replace: true,
template: '<a class="someclass"></a>',
terminal: true,
priority: 1000,
link: function (scope, element, attributes) {
element.removeAttr('link'); // Remove the attribute to avoid indefinite loop.
element.attr('ng-click', 'linkClicked(\'' + attributes.text + '\')');
$compile(element)(scope);
},
};
}
})();
$scope.linkClicked = function(text){...}
element.attr('ng-click', 'abc.linkClicked(..)')
(父级的controllerAs为abc) - 也可以。问题是我不知道哪个控制器将使用我的指令,并且不能对其中的'abc'名称进行硬编码。
你有什么建议我应该做的?
答案 0 :(得分:1)
从您的问题中很难理解您所面临的所有限制因素,但如果您获得的唯一HTML就是:
<link text="some text">
你需要生成对某些函数的调用,然后该函数必须是:
#1 是有问题的,因为该指令的用户现在需要了解其内部。尽管如此,如果您假设函数名称为linkClicked
(或者您想要调用的任何名称),那么它是可能的,并且您的指令的用户必须特别注意别名他真正需要的函数的别名(可以使用&#34; controllerAs&#34;也可以):
<div ng-controller="FooCtrl as foo" ng-init="linkClicked = foo.actualFunctionOfFoo">
...
<link text="some text">
...
</div>
app.directive("link", function($compile){
return {
transclude: "element", // remove the entire element
link: function(scope, element, attrs, ctrl){
var template = '<a class="someclass" ng-click="linkClicked(\'' +
attrs.text +
'\')">link</a>';
$compile(template)(scope, function(clone){
element.after(clone);
});
}
};
});
<强> Demo 强>
#2 通常是通过属性实现的,在您的情况下这是不可能的。但你也可以创建一种&#34;代理&#34;指令 - 让我们称之为onLinkClick
- 它可以执行你需要的任何表达式:
<div ng-controller="FooCtrl as foo"
on-link-click="foo.actualFunctionOfFoo($data)">
...
<link text="some text">
...
</div>
link
指令现在需要require: "onLinkClick"
:
app.directive("link", function($compile){
return {
transclude: "element", // remove the entire element
scope: true,
require: "?^onLinkClick",
link: function(scope, element, attrs, ctrl){
if (!ctrl) return;
var template = '<a class="someclass" ng-click="localClick()">link</a>';
scope.localClick = function(){
ctrl.externalFn(attrs.text);
};
$compile(template)(scope, function(clone){
element.after(clone);
});
}
};
});
app.directive("onLinkClick", function($parse){
return {
restrict: "A",
controller: function($scope, $attrs){
var ctrl = this;
var expr = $parse($attrs.onLinkClick);
ctrl.externalFn = function(data){
expr($scope, {$data: data});
};
},
};
});
<强> Demo 强>
请注意,link
指令也会在<link>
内的<head>
上执行。因此,尝试检测它并跳过所有内容。出于演示目的,我使用了一个名为blink
的指令来避免此问题。