创建具有可变元素类型指令 [英] Creating a directive with a variable element type
问题描述
我试图创造一个指令,将使用一个下拉的大,中,小选择更改HTML元素类型(H1 / H2 / H3)。我希望它也保留了元素的属性。我创建了这个例子的小提琴: http://jsfiddle.net/H63Z3/1/
I'm trying to create a directive that will change the html element type (h1/h2/h3) by using a drop down selector of "Large", "Medium", "Small". I want it to also retain attributes on the element. I have created a fiddle of this example: http://jsfiddle.net/H63Z3/1/
角:
angular.module('app', [])
.controller('example', function ($scope) {
$scope.type = 'h2';
})
.directive('changeType', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attributes) {
scope.$watch('type', function () {
var attrs = element[0].attributes;
var newElement = $('<' + scope.type + '>').text(element.text());
for (var i = 0; i < attrs.length; i++) {
newElement.attr(attrs.item(i).name, attrs.item(i).value);
}
element.replaceWith(newElement);
$compile(element.contents())(scope);
});
}
};
});
&HTM放大器; L:
HTM & L:
<div ng-app="app" ng-controller="example">
<select ng-model="type" ng-options="k as v for (k,v) in { h1: 'Large', h2: 'Medium', h3: 'Small' }"></select>
<h1 change-type>Text</h1>
<div>{{ type }}</div>
</div>
我看到的问题是,元素属性没有被正确更新角度的改变是由做滴下来以后。如此看来,该指令不重新应用到新的元素。我不确定如果使用编译功能是正确的答案。
The problem I see is that the element property is not being updated properly in Angular after a change is made by the drop down. It seems that the directive is not reapplied to the new element. I'm unsure if using a compile function is the right answer.
任何帮助将大大AP preciated。
Any help would be greatly appreciated.
推荐答案
我只花了一小会儿什么,我决定称之为古灵精怪的指令工作。这是pretty乐趣居然和我很高兴的结果。请注意,这个解决方案是纯粹的角。
I just spent a little while working on what I decided to call a 'morphling' directive. It was pretty fun actually, and I'm quite pleased with the result. Note that this solution is pure Angular.
注意:我没有注意到,当我第一次张贴了这个,你需要持久化属性。因为我已经加入该功能。添加我的属性编译后,但如果你想提供指令作为属性,你必须围绕做的其他方式。
Note: I failed to notice when I first posted this that you required persistent attributes. I have since added that functionality. I add my attributes after compilation, but if you want to supply directives as attributes, you'd have to do it the other way around.
<h1>AngularJS 'Morphling' Directive</h1>
<div ng-app="app" ng-controller="morphTest">
<strong>Morphling directive type:</strong> <select ng-model="type" ng-options="tag as caption for (tag, caption) in { h1: 'Heading 1', h2: 'Heading 2', h3: 'Heading 3', li: 'List Item', quote: 'Quote', attrDemo: 'Attribute Persistence Demo' }"></select><br />
<morphling type="type" attr="value">Normal <span style="color: red">{{bindingDemo}}</span> Works</morphling>
</div>
LESS
html, body {
font-family: sans-serif;
color: #111;
}
quote {
display: block;
margin: 20px;
font-style: italic;
&:before,
&:after {
content: '"';
}
}
attrDemo[attr="value"] {
display: inline-block;
color: blue;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
}
的JavaScript
angular.module('app', [])
.controller('morphTest', function ($scope) {
$scope.type = 'h2';
$scope.bindingDemo = 'Binding';
})
.directive('morphling', function ($compile) {
return {
restrict: 'E',
replace: true,
link: function(scope, element, attributes) {
var e = element;
scope.$watch(attributes.type, function(type){
type = !!type ? type : 'span';
var e2 = $compile('<' + type + '>' + e.html() + '</' + type + '>')(scope);
for(var a in attributes.$attr) {
if(a.toLowerCase() != 'type')
e2.attr(a, attributes[a]);
}
e.replaceWith(e2);
e = e2;
});
}
};
});
演示
这篇关于创建具有可变元素类型指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!