如何replaceAngularJS指令链接函数中的元素?
我创build了一个需要用一个可以包含任何HTML代码的dynamic模板replace自己的<row>
AngularJS指令( <row>
标记不能在DOM中出现)。
使用replace: true
的问题是,它不能与表的<tr>
标签一起工作,而且模板是dynamicselect的。
所以我试图find一种方法来replace链接函数中的元素,但没有成功。
使用jQuery的.replaceWith()
打破ngRepeat
为未知的原因。
任何提示?
这是小提琴
你的小提琴似乎很基本,但你应该能够使用outerHTML
element[0].outerHTML ='<div>I should not be red</div>';
更新小提琴
如果你必须处理ng-repeat
你可以将你的项目绑定到一个scope属性,并在你编译的模板中引用它们。 一旦编译完成,你可以使用jQuery replaceWith()
HTML
<row items="items">***</row>
指示
.directive('row', function ($compile) { return { restrict: 'E', scope: { items: "=" }, link: function (scope, element, attrs) { var html ='<div ng-repeat="item in items">I should not be red</div>'; var e =$compile(html)(scope); element.replaceWith(e); } }; });
ng-repeat
示例
马克的答案将起作用,然而,这个例子太有限,无法展示整个图景。 鉴于马克的指示可能确实足够普通和简单的用户界面组件,对于更复杂的操作,该模式是一个可以避免的。 下面我详细的解释一下这个背后的原因。 事实上,Angular 已经提供了一种更简单的方法来用模板replace指令元素。 它可以在这个答案的底部find。
下面是一个指令如何在幕后看到:
.directive('row', function ($compile) { return { restrict: 'E', scope: { items: "=" }, // Whether you define it this way or not, this is the order of // operation (execution) behind every AngularJS directive. // When you use the more simple syntax, Angular actually generates this // structure for you (this is done by the $compile service): compile: function CompilingFunction($templateElement, $templateAttributes, transcludeFn) { // The compile function hooks you up into the DOM before any scope is // applied onto the template. It allows you to read attributes from // the directive expression (ie tag name, attribute, class name or // comment) and manipulate the DOM (and only the DOM) as you wish. // When you let Angular generate this portion for you, it basically // appends your template into the DOM, and then some ("some" includes // the transclude operation, but that's out of the $scope of my answer ;) ) return function LinkingFunction($scope, $element, $attrs) { // The link function is usually what we become familiar with when // starting to learn how to use directives. It gets fired after // the template has been compiled, providing you a space to // manipulate the directive's scope as well as DOM elements. var html ='<div ng-repeat="item in items">I should not be red</div>'; var e = $compile(html)($scope); $element.replaceWith(e); }; } }; });
我们能做些什么呢? 显而易见的是,手动调用两次相同DOM布局的$compile
是多余的,对性能不利,也不好。 你应该怎么做? 简单地编译你的DOM 应该被编译的地方:
.directive('row', function ($compile) { return { restrict: 'E', template: '<div ng-repeat="item in items">I should not be red</div>', scope: { items: "=" }, compile: function CompilingFunction($templateElement, $templateAttributes) { $templateElement.replaceWith(this.template); return function LinkingFunction($scope, $element, $attrs) { // play with the $scope here, if you need too. }; } }; });
如果你想深入了解指令的内幕,下面是我所称的非官方AngularJS指令参考
一旦你完成了这个头在这里: https : //github.com/angular/angular.js/wiki/Understanding-Directives
现在,按照承诺,这里是你来这里的解决scheme:
使用replace: true
:
.directive('row', function ($compile) { return { restrict: 'E', template: '<div ng-repeat="item in items">I should not be red</div>', replace: true, scope: { items: "=" } }; });