實際上link其實是由$compile生成的函數,而且這個函數在生成的時候內容已經定好了,所以在調用link函數的時候只是
傳對應的scope參數給這些由$compile編譯好的link函數,所以如果想通過cloneAttachFn這個傳入link的回調函數來修改dom結構是不行的。
$compile
最基本的使用方式:
var link = $compile('<p>{{ text }}</p>'); var node = link($scope); console.log(node);
上面的 $compile
和 link
調用時都有額外參數來實現其它功能。先看 link
函數,它形如:
function(scope[, cloneAttachFn]
第二個參數 cloneAttachFn
的作用是,表明是否複製原始節點,及對複製節點需要做的處理,下面這個例子說明了它的作用:
<div ng-controller="TestCtrl"></div> <div id="a">A {{ text }}</div> <div id="b">B </div>
app.controller('TestCtrl', function($scope, $compile){ var link = $compile($('#a')); //true參數表示新建一個完全隔離的scope,而不是繼承的child scope var scope = $scope.$new(true); scope.text = '12345'; //var node = link(scope, function(){}); var node = link(scope); $('#b').append(node); });
cloneAttachFn
對節點的處理是有限制的,你可以添加 class
,但是不能做與數據綁定有關的其它修改(修改了也無效):
app.controller('TestCtrl', function($scope, $compile){ var link = $compile($('#a')); var scope = $scope.$new(true); scope.text = '12345'; var node = link(scope, function(clone_element, scope){ clone_element.text(clone_element.text() + ' ...'); //無效 clone_element.text('{{ text2 }}'); //無效 clone_element.addClass('new_class'); }); $('#b').append(node); });
修改無效的原因是,像 {{ text }}
這種所謂的 Interpolate 在 $compile
中已經被處理過了,生成了相關函數(這裏起作用的是 directive
中的一個 postLink
函數),後面執行 link
就是執行了$compile
生成的這些函數。當然,如果你的文本沒有數據變量的引用,那修改是會有效果的。
前面在說自定義指令時說過, link
函數是由 compile
函數返回的,也就像前面說的,應該把改變 DOM 結構的邏輯放在 compile
函數中做。