Reputation: 2773
I'm trying to have Two-Way binding on a directive.
I can't use the scope
on the directive (multiple directives on element), so I'll have to do it in the compile(){...}
function
This is a simplified version of the directive so far:
.directive('myDialog', function() {
return {
restrict: 'E',
templateUrl: 'my-dialog.html',
compile: function(tElement, tAttrs, transclude) {
return function($scope, $element, $attributes) {
$scope.label = $scope.$eval($attributes.label);
// when I set the label on something this should update the parent
$scope.label = "test";
}
}
};
So how can I make it that when I change the lable in my directive it updates the value in the main application, and visa versa
Plunker for testing: http://plnkr.co/edit/lARCrGD5FsnOWQZrahIl?p=preview
UPDATE: here is the actual setup with all the logic for what I'm trying to archieve: http://codepen.io/cskiwi/pen/eJryqK?editors=1010
On line 101 i want to set the testing var on true, later one I'm also going to set to testing var on false outside that directive
UPDATE2: Got something, that is maybe something to lookinto:
return {
restrict: "A",
require: ["^mdChips", "^chipBar"],
controller: "chipBarController",
controllerAs: "chipBarController",
bindToController: {
activated: "="
},
// rest of the code
this is allowing to set the activated var to true from in the directive; but now I can't set the value from my appCtrl back to false
Upvotes: 0
Views: 158
Reputation: 5353
I agree with coments saying that you have probably a design problem but 'ill give you a way to do what you want.
Use ng-model directive and controller then with that you can read/watch for change/change the value :)
See tutorial here : https://www.nadeau.tv/using-ngmodelcontroller-with-custom-directives/
EDIT : well if you can use proper binding i have a quite dirty and tricky way of doing it : Based on this documentation : https://docs.angularjs.org/api/ng/function/angular.element
Add an attribute which will contains the field path as a string in controller scope (a.b.c if it's in $scope.a.b.c) like this
Get the parent element of your directive with angular.element() and get his scope with the scope method (in the documentation). Then call the $eval method if this scope like this to read theScope.$eval(attrs.fieldsPath); and with the $eval you should be able to update values too with theScope.$eval(attrs.fieldsPath+='myValue'). If it doesn't work you'd have to split your string with '.' and navigate through the scope object to write on the right field.
var value = $scope;
var tab = attrs.fieldPath.split('.');
for(i = 0; i < tab.length && value; i++){
value = value[tab[i]];
}
Upvotes: 0
Reputation: 2773
The update2 was actually fixing the issue.
controllerAs: "chipBarController",
bindToController: {
activated: "="
},
did everything it needed,
had just a typo in my code
Thanks Everyone who helped, especially @Claies
Upvotes: 0
Reputation: 4728
her is a working plunker with data binding http://plnkr.co/edit/qtfEPfbNTZHHUEBhGYye?p=preview
there is a lot of detailled reading over the net
http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope
You should create a scope variable for your directive to let the directive know which variable to bind one
<div ng-controller="Controller">
{{email}} <== should become test on launch
<my-dialog email="email"></my-dialog>
<button ng-click="click()">click</button> <== should turn both in tst
</div>
<div class="alert">
email is :- {{email}}!
</div>
angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
$scope.email = '[email protected]';
$scope.click = function(){
$scope.email = "tst";
}
}])
.directive('myDialog', function() {
return {
restrict: 'E',
scope : { // this create an isolated scope
email:'=' // the email attribute is binded two way with '=', there is also '@' and '&'
},
templateUrl: 'my-dialog.html'
};
});
Upvotes: 1