[英]Transcluding ng-click in a directive
我正在構建一個AngularJS指令。 我希望該指令包含其中包含ng-click的其他內容。 單擊時,生成的按鈕不會執行任何操作。 這是我嘗試的代碼的簡化版本:
(HTML)
<div ng-app="someapp">
<div ng-controller="Ctrl1">
<h2>Example</h2>
<my-dir data-x="1">
<button ng-click="refresh()" id="refresh1">Refresh</button>
</my-dir>
<my-dir data-x="2">
<button ng-click="refresh()" id="refresh2">Refresh</button>
</my-dir>
</div>
</div>
(JavaScript的)
var app = angular.module('someapp', []);
app.controller('Ctrl1', function($scope){ });
app.directive('myDir', function(){
return {
restrict: 'E',
scope: {},
template: '<div><p>Directive contents:</p><div ng-transclude></div></div>',
transclude: true,
link: function(scope, element, attrs){
$scope.y = attrs.x+1;
scope.refresh = function(){
console.log("Refresh Called, y = ", $scope.y);
}
}
};
});
如何更改它以便按鈕實際觸發$ scope.refresh()函數?
額外說明:
我需要指令的本地對象信息(單個控制器中可能有多個此指令),因此我創建了一個新的作用域。
正如dcodesmith指出的那樣,轉換的ng-click將綁定到控制器的范圍而不是指令的范圍。 根據您想要做什么,您可能希望這是行為(因為被轉換的內容不是指令的一部分,為什么它應該調用指令范圍的方法?)。 就個人而言,我會在控制器的范圍內聲明該方法。
app.controller('Ctrl1', function($scope){
$scope.refresh = function() {
console.log("Refresh called.");
};
});
在這種情況下,您的指令應聲明隔離范圍,即使其中沒有任何內容。
更新:根據您的評論,為什么不在指令模板中包含按鈕? 在這種情況下,它已經與正確的范圍相關聯。
如果在某些情況下您不需要刷新按鈕,則通過指令將其作為選項公開為屬性:
<my-dir show-button='true'></my-dir>
// directive scope
scope: {
showButton: '='
}
我使用這種方法的最大問題是使用“雙向綁定”運算符(=)來使'true'和'false'被視為表達式。 我只是不喜歡那種感覺。
無論如何,希望這可以解決你的問題...還有一個評論,我說這甚至不知道你實現的是什么實際上是一個刷新按鈕,但如果是,我會花一點時間考慮你是否真的需要一個“刷新”按鈕。 Angular擅長消除刷新按鈕!
更新2:
我創建了一個plunkr,顯示我認為我會如何處理你的情況,特別是如果重用任何其他控件:
http://plnkr.co/edit/FhrSwcrSZScvCfhtCSjn
在這個例子中,兩個按鈕指令實際上是“videoPlayer”指令的子代。 它們的邏輯包含在該指令中,但它們是單獨實例化的,並且父指令不需要操作。 “父指令”(videplayer)簡單地公開了要使用的“孩子”的API。 也不是父類的方法是構造函數的方法,而不是范圍。 我認為這很奇怪,但它完全取自角度文檔:
http://docs.angularjs.org/guide/directive (頁面上的最后一個例子)
請注意,每個videoPlayer指令仍然擁有自己的隔離范圍。
刪除scope
對象。 那里似乎發生了沖突。
transclude選項更改范圍嵌套的方式。 它使得transcluded指令的內容具有指令之外的任何范圍,而不是內部的任何范圍。 這樣做,它使內容訪問外部范圍。
app.directive('myDir', function(){
return {
restrict: 'E',
//scope: {}, remove this line.
template: '<div><p>Directive contents:</p><div ng-transclude></div></div>',
transclude: true,
link: function(scope, element, attrs){
console.log("X-attr", attrs.x);
scope.refresh = function(){
console.log("Refresh Called");
}
}
};
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.