Max Taylor Max Taylor - 2 months ago 4
AngularJS Question

Variable exchange between directive and controller in Angular

I know this has been asked loads of times but I can't seem to find an appropriate answer for my case.

At the moment I have a form to "invite more people" that takes a name and email.
Underneath that form is a button "invite more friends" that will trigger a directive "add-more-person" which will add another form.

I want people to not be able to invite more than 10 friends. when there are 10 'invite-a-friend-forms' I want the button to be hidden.

So I added a counter in the directive so that you won't be able to add more forms after there are 10, and a boolean "addFriends" to my controller.

Now I want my boolean addFriends to be changed to false whenever the directive's counter reaches a certain amount.

I can't achieve this using $watch since I'm not using $scope and all the other things I tried have failed aswell.

This is what my code looks like:

<div class="row">
<div class="column medium-6">
<button ng-show="post.addFriends" class="btn-grey" type="button" add-more-person add-friends="post.addFriends">Invite more people</button>
</div>
<div class="column medium-6">
<button class="btn-green" type="button">Send</button>
</div>
</div>


directive:

(function() {
'use strict';

angular.module('app').directive('addMorePerson', addMorePerson);

function addMorePerson($rootScope, $window, $timeout) {
return {
restrict: 'A',
scope: {
addFriends: '='
},
link: function(scope, elem, attr) {
var counter = 0;
console.log('start: ' + scope.addFriends);

elem.bind('click', appendInput);

function appendInput() {

if(counter < 2) {
var myEl = angular.element(document.querySelector('#content-form'));

var template = '<div class="content">' +
'<div class="form-page">' +
'<div class="form-field">' +
'<label class="form-label">Naam:</label>' +
'<div class="form-controls">' +
'<input kl_virtual_keyboard_secure_input="on" type="text">' +
'</div>' +
'</div>' +
'<div class="form-field">' +
'<label class="form-label">E-mail <span>(verplicht)</span>:</label>' +
'<div class="form-controls">' +
'<input type="email">' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
myEl.append(template);
counter++;
} else {
scope.addFriends = false;
console.log('after: ' + scope.addFriends);
return;
}
}
}
};
}
})();


and Controller:

(function() {
'use strict';

angular
.module('app')
.controller('PostDonateController', postDonateController);

function postDonateController(apiFactory, $sessionStorage, $localStorage, $state, $stateParams) {

var that = this; // jshint ignore: line

that.addFriends = true;

}
})();


I left out all my other code to make it more readable. So my console logs in the directive tell me that it does indeed start at true and after 3 clicks it turns to false. But this value is not passed on to my controller and therefore not hiding the button. Any ideas how I could achieve this?

Answer

call scope.$apply(); at list line of your append function, it'll perform sync between directive and controller. You should do that because you append template outside of angular context.

But your solution is awkward, you should append templates via ng-repeat.

Comments