考虑以下指令:
angular.module('MyApp').directive('maybeLink', function() {
return {
replace: true,
scope: {
maybeLink: '=',
maybeLinkText: '='
},
template: '<span>' +
' <span ng-hide="maybeLink" ng-bind-html="text"></span>' +
' <a ng-show="maybeLink" href="#" ng-bind-html="text"></a>' +
'</span>',
controller: function($scope) {
$scope.text = $scope.maybeLinkText.replace(/\n/g, '<br>');
}
};
});
该指令将<span>
和<a>
添加到DOM(一次只能看到一个)。
我怎样才能重写指令,以便将 <span>
或<a>
添加到DOM中,但不能同时添加?
更新
好的,我想我可以这样使用ng-if
:
template: '<span>' +
' <span ng-if="!maybeLink" ng-bind-html="text"></span>' +
' <a ng-if="maybeLink" href="#" ng-bind-html="text"></a>' +
'</span>'
但是,在这种情况下怎么能摆脱周围的<span>
?
更新2
以下是使用$compile
的指令版本。它没有周围的<span>
,但双向数据绑定也不起作用。我真的很想知道如何修复双向数据绑定问题。有什么想法吗?
angular.module('MyApp').directive('maybeLink', function($compile) {
return {
scope: {
maybeLink: '=',
maybeLinkText: '='
},
link: function(scope, element, attrs) {
scope.text = scope.maybeLinkText.replace(/\n/g, '<br>');
if (scope.maybeLink) {
element.replaceWith($compile('<a href="#" ng-bind-html="text"></a>')(scope));
} else {
element.replaceWith($compile('<span ng-bind-html="text"></span>')(scope));
}
}
};
});
答案 0 :(得分:42)
您可以使用template
功能。根据{{3}}:
您可以将模板指定为表示模板的字符串,或者指定为函数,该函数接受两个参数tElement和tAttrs(在下面的编译函数api中描述)并返回表示模板的字符串值。 / p>
function resolveTemplate(tElement, tAttrs) {
}
angular.module('MyApp').directive('maybeLink', function() {
return {
//...
template: resolveTemplate,
//...
};
});
答案 1 :(得分:30)
我认为这是基于范围属性注入动态模板的最简洁方法
angular.module('app')
.directive('dynamic-template', function () {
return {
template:'<ng-include src="template"/>',
restrict: 'E',
link: function postLink(scope) {
scope.template = 'views/dynamic-'+scope.type+'.html';
}
};
})
答案 2 :(得分:5)
我最后想出了以下版本:
angular.module('MyApp').directive('maybeLink', function($compile) {
return {
scope: {
maybeLink: '=',
maybeLinkText: '='
},
link: function(scope, element, attrs) {
scope.$watch('maybeLinkText', function(newText) {
scope.text = newText.replace(/\n/g, '<br>');
});
scope.$watch('maybeLink', function() {
var newElement;
if (scope.maybeLink) {
newElement = $compile('<a href="#" ng-bind-html="text"></a>')(scope);
} else {
newElement = $compile('<span ng-bind-html="text"></span>')(scope);
}
element.replaceWith(newElement); // Replace the DOM
element = newElement; // Replace the 'element' reference
});
}
};
});
答案 3 :(得分:3)
我会使用ng-switch
。
类似
template: '<span ng-switch on="maybeLink">' +
' <span ng-switch-when="http://www.yahoo.com" ng-bind-html="text"></span>' +
' <a ng-switch-when="http://google.com" href="#" ng-bind-html="text"></a>' +
'</span>',
或
template: '<span ng-switch on="maybeLink">' +
' <span ng-switch-when={{maybeLink.length == 0}} ng-bind-html="text"></span>' +
' <a ng-switch-when={{maybeLink.length > 0}} href="#" ng-bind-html="text"></a>' +
'</span>',
所以这是方向
答案 4 :(得分:2)
您可以将ng-if用于相同的
以下是工作示例
指令代码:
angular.module('MyApp').directive('maybeLink', function() {
return {
replace: true,
scope: {
maybeLink: '=',
maybeLinkText: '='
},
template: '<span>' +
' <span ng-if="!maybeLink.link" ng-bind-html="text"></span>' +
' <a ng-if="maybeLink.link" href="#" ng-bind-html="text"></a>' +
'</span>',
controller: function($scope) {
$scope.text = $scope.maybeLinkText.replace(/\n/g, '<br>');
}
};
});
答案 5 :(得分:1)
以下是提供动态更新的解决方案。用法:
<a rewrite-as-span="true"></a>
<a rewrite-as-span="false"></a>
<a rewrite-as-span="yourFn()"></a>
等。
app.directive('rewriteAsSpan', function($compile){
return {
restrict: 'A',
template: '<span />',
replace: true,
// we transclude the element because when it gets replaced with the span
// we want all the properties from the original element
transclude: 'element',
compile: function(tElement, tAttrs){
return {
post: function(scope, element, attrs, controller, transclude){
var rewrittenEl, originalEl;
transclude(scope, function(clone){
originalEl = clone;
});
scope.$watch(attrs.rewriteAsSpan, function(value){
if (value === undefined || value === true){
if (!rewrittenEl){
// lazy compile and cache the rewritten element
transclude(scope, function(clone){
rewrittenEl = tElement;
rewrittenEl.html(clone.html());
// remove this directive because the $compile would get infinite
rewrittenEl.removeAttr('rewrite-as-span');
$compile(rewrittenEl)(scope);
});
}
element.replaceWith(rewrittenEl);
element = rewrittenEl;
} else {
element.replaceWith(originalEl);
element = originalEl;
}
});
}
};
}
};
});
代码和规格为gist