angular 指令:在两个模板之间动态切换
angular directive: switch between two templates dynamically
我正在尝试创建一个名为 availableTo
的指令,它可以根据某些消息在两个不同的模板之间切换。例如,如果该字段是带有 ng-model
指令的 input
,我首先需要使用 <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 .这对我来说似乎是不可能完成的任务,但我想听听一些专家的意见。谢谢
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>
.
之间切换
我正在尝试创建一个名为 availableTo
的指令,它可以根据某些消息在两个不同的模板之间切换。例如,如果该字段是带有 ng-model
指令的 input
,我首先需要使用 <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 .这对我来说似乎是不可能完成的任务,但我想听听一些专家的意见。谢谢
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>
.