我正在尝试创建一个名为availableTo
的指令,它可以根据某些消息在两个不同的模板之间切换。例如,如果字段是带有input
指令的ng-model
,我首先需要使用<span>
标记将其更改为只读。到目前为止,我的代码可以将视图切换为只读,但我似乎无法将其切换回input
:
var directive = {
restrict: 'A',
require: '?ngModel',
link: linkerFn,
replace: true
};
function linkerFn(scope, element, attrs, ngModelCtrl) {
var clonedElement = angular.copy(element);
var preOuterHTML = clonedElement[0].outerHTML; //this can save the <input> field html code
scope.$on('mode_changed', function() {
var curUserRole = userservices.getUserRole();
if (attrs.availableTo == curUserRole) {
var e = $compile(preOuterHTML)(scope);
element.replaceWith(e);
} else {
var template = '<span>' + ngModelCtrl.$viewValue + '</span>';
var e = $compile(template)(scope);
element.replaceWith(e);
}
}); //scope.$on
} //linkerFn
对于input
字段:
<input name="test1" class="form-control" ng-model="name" placeholder="Name 1" available-to="ADMIN"/>
我还注意到,一旦我在上面的else
块中更改了模板,元素就会重新渲染,preOuterHTML
不再包含原始元素html。这似乎是我不可能完成的任务,但我想听听一些专家的意见。感谢
答案 0 :(得分:3)
element.replaceWith(e);
不要这样做。在Angular中,如果您发现自己试图直接修改DOM,那么根据定义,您做错了。你必须坐下来让Angular完成工作。
如果您需要替换指令的整个模板,一种相当简单的方法是将ng-include与包含所需条件templateUrl
的范围变量一起使用,例如
var directive = {
// ...
template: '<div ng-include="myTemplateUrl"></div>',
link: function(scope, el) {
if (/* whatever */) {
scope.myTemplateUrl="templates/foo.html";
} else {
//...etc
}
},
};
(这确实为树添加了一个额外的DOM节点,但这通常是无害的。)
听起来在你的情况下,你可能不需要那么远;模板中的简单ng-if
可能足以在您的只读<span>
和<input>
之间切换。