Reputation: 62384
Within a directive, I'd like to modify the expression's value when a button is clicked. The below code is only modifying the value locally within my directive. I'd like to change the value outside of this directive as well. How can I accomplish that?
scope: false,
link: function (scope, el, attrs) {
//toggle the state when clicked
el.bind('click', function () {
scope[attrs.ngModel] = !scope[attrs.ngModel];
});
Plunker: http://plnkr.co/edit/xqYBnz5BHLP844kXJXKs?p=preview
Upvotes: 0
Views: 1104
Reputation: 54514
Since you are not creating a new scope, then you should be able to access the model via scope
not attrs
In the directive, change the scope to
scope: {
ngModel: '='
},
And change the scope.$apply to
scope.$apply(function () {
if (scope.ngModel) {
off();
scope.ngModel = false;
} else {
on();
scope.ngModel = true;
}
});
Upvotes: 0
Reputation: 42669
The problems is with the binding expression in ng-model. Since it has '.' in it, you need to use the $parse
to get and set value correctly. See some documentation here
Something like
var getter=$parse(attrs.ngModel);
var setter=getter.assign;
setter(scope,!getter(scope));
See my updated plunkr here http://plnkr.co/edit/VAE43y5cagCF8jq5AlaY?p=preview
Basically setting
scope[attrs.ngModel] = !scope[attrs.ngModel]
creates a new property user.active
. To set it should be scope['user']['active'];
Upvotes: 4
Reputation: 7743
An alternative way would be to create an isolate scope and pass in your directive an attribute that will link it to a method in the parent scope which will do the work of flipping the state.
Rough example:
In your directive definition:
scope: {
flipState: '&'
},
link: function (scope, elem, attr) {
elem.bind('click', function () {
flipState();
}
}
In your view:
<div ng-controller="MyController">
/* ... */
<button directivename flip-state="flipStateFunc()"></button>
</div>
And in your controller MyController
:
flipStateFunc: function () {
$scope.state = !$scope.state;
}
Upvotes: 0