Reputation: 12718
I'm trying to change a scope value in a parent controller from a child directive.
I've added =
for two-way binding such that when I click on a the directive's <tr>
, it will fire openDetail
, which will update scope.page
, which has been two-way bound.
Yet it's not updating the controller's page
value.
Controller HTML:
TEST : {{page}} //Not changed
<questions-list></questions-list>
Controller:
$scope.page = 'Not changed';
Directive HTML:
<tr ng-repeat="q in questions" ng-click="openDetail( q.id )">
"Questions List" Directive:
scope: {
page : '='
},
...
scope.openDetail = function (id) {
scope.page = 'question_detail';
};
In other examples, the ng-click
handlers are always bound on the Controller. In my case, I need to fire an event from the directive, change directive value, and have it update the controller.
Upvotes: 0
Views: 2994
Reputation: 4395
You should pass the parent scope's property to bind to via directive's element attribute:
<questions-list page="page"></questions-list>
Here the demo.
Upvotes: 3
Reputation: 876
I can give you some different methods doing this .
Once consider your must pass values from controller to directive
like
scope: {
page : '='
},
then
You can't access parent scope so need to transclude your child scope hence but it seems deprecated in some versions.
hence best practice is to share page variable with $rootScope.page first inject $rootScope in both controller and directive Injections and use
{{$root.page}} // in controller
//and in directive function make this change
scope.openDetail = function (id) {
$rootScope.page = 'question_detail';
};
Also if you need other ways like #BROADCAST or #EMIT ( really great thing in angularjs)
/// in directive
$rootScope.$emit("emitName", {page:"page value" });
// in controller
$rootScope.$on("emitName",function(event,data){
$scope.page = data.page; // this comes from directive and assign to current scope's page variable
});
Please let me know if anyone works for you otherwise we can research more.
Upvotes: 0
Reputation: 1445
I see a mistacke on your html :
<tr ng-repeat="q in questions ng-click="openDetail( q.id )">
must be replace by
<tr ng-repeat="q in questions" ng-click="openDetail( q.id )">
It missing a quote.
And for the problem, you use a primitive type to bind on directve. Try to encapsulate the value into an object on your parent scope :
$scope.page = { value: 'Not changed' };
<questions page="page.value">...</questions>
Upvotes: 0
Reputation: 5264
I created a sample App for you
var app = angular.module('test', []);
app.controller('testCon', function($scope) {
$scope.page = "Parent controll";
});
app.directive('questions', function() {
return {
scope: true,
controller: ['$scope',
function($scope) {
}
]
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="testCon">
{{page}}
<questions>{{page}}</questions>
</div>
Upvotes: -1