Reputation: 1517
I have the following Angular custom directive code:
Template (ReviewStandards.html)
<div class="review-standard" ng-repeat="standard in standards">
<button ng-click="mark(standard)">Mark Complete</button>
</div>
JS
app.directive("reviewStandards", function ($parse, $state) {
return {
restrict: "A",
templateUrl: function (elements, attrs) {
return "/Scripts/App/Directives/Templates/ReviewStandards.html";
},
transclude: false,
scope: {
standards: "="
},
replace: true,
link: function (scope, elem, attrs) {
scope.mark = function (standard) {
alert();
};
}
};
});
The directive is used as:
<div review-standards standards="review.ReviewStandards"></div>
Where standards
is just a JSON array of standard
objects.
Problem is that the the ng-click
is not firing the function when the button is clicked. The scope is isolated - is this something to do with this or the fact that the button is in an ng-repeat
?
Upvotes: 1
Views: 807
Reputation: 2547
Try This, "i just remove the Replace from your codes"
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
$scope.data = [{
name: "a"
},
{
name: "b"
}
];
});
app.directive("reviewStandards", function() {
var template = "<div class=\"review-standard\">" +
"<div ng-repeat=\"standard in standards\">" +
"{{standard.name}} " +
"<button ng-click=\"mark(standard)\">Mark Complete</button>" +
"<div><hr>" +
"</div>";
return {
restrict: "A",
transclude: false,
template: template,
scope: {
standards: "="
},
link: function(scope, elem, attrs) {
scope.mark = function(standard) {
console.log(standard)
};
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div review-standards standards="data"></div>
</div>
Upvotes: 6
Reputation: 13381
I'll try a bit explain why this happens.
Problems here with scope inheritance when using replace:true and in template just one element with ng-repeat.
If replace:false, template paste inside element with directive, so you get something like this
<div review-standards standards="review.ReviewStandards"> <!-- here isolated scope from review-standards directive -->
<div class="review-standard" ng-repeat="standard in standards"> <!-- here child scope created with ng-repeat -->
<button ng-click="mark(standard)">Mark Complete</button>
</div>
</div>
So, child scopes that created by ng-repeat inherits from isolated scope review-standards directive, and all property from isolated scope available in children scopes.
When used replace:true, template replace element with directive, si you get something like this
<div class="review-standard" ng-repeat="standard in standards" review-standards standards="review.ReviewStandards"> <!-- here child scope created with ng-repeat -->
<button ng-click="mark(standard)">Mark Complete</button>
</div>
And most interesting in this case, that now children scopes inherited from ng-controller, but $parent
property setup to isolated scope review-standards directive. So in children scope available all properties from ng-controller scope but not available from isolated scope review-standards directive.
Simplest way for solution, as suggest in nearby answer, just remove replace:true
Yet another way: a bit change template, like this
<div>
<div class="review-standard" ng-repeat="standard in standards">
<button ng-click="mark(standard)">Mark Complete</button>
</div>
</div>
Or a bit ugly solution: use $parent property instead hoping on inheritance
<div class="review-standard" ng-repeat="standard in $parent.standards">
<button ng-click="$parent.mark(standard)">Mark Complete</button>
</div>
Upvotes: 2