NPanda NPanda - 22 days ago 5
AngularJS Question

AngularJS update value in a directive

I have a problem when trying to change the value of a variable from a directive.

I did a plunker so it is more understandable because I cannot explain it correctly.
I have two buttons list :


  • One is composed of three buttons, which are displayed when ng-show is true. (the 'module' variable in the plunker)

  • And another one composed of others buttons which change this 'module' variable.



The thing is, when I change the 'module' variable in clicking a button in the second list [it actually calls a function], the directive does not update it, so the first list of buttons is not updated too. (the first button is still displayed but it should disappear and make another button pop).

So I read a few topics about it, I found that I should do a watch function in the directive to catch all changes. But it does not work. It only passes one time and it is at the beginning.

// index.html
<!DOCTYPE html>
<html>

<head>
<link data-require="bootstrap-css" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" />
<link data-require="bootstrap@*" data-semver="4.0.0-alpha.2" rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"> </script>
<script data-require="angular.js@*" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
<script src="script.js"></script>
<script src="appDirective.js"></script>
<script src="appController.js"></script>
</head>

<body ng-app="tmp">
<app-module module="1" id="module"></app-module>
<button onClick="changeModule(2)">Change to 2</button>
<button onClick="changeModule(3)">Change to 3</button>
</body>

</html>


// script.js
angular.module('tmp', []);

changeModule = function(value) {
console.log(value);
$('#module').attr('module', value);
}


// appDirective.js

'use strict';
angular.module('tmp')

.directive('appModule', function() {

return {
restrict: 'AE',
templateUrl: "app.html",
controller: "appController",
scope: {
state: "@",
'module' : '@'
},
link: function($scope) {
$scope.$watch('module', function(newVal) {
console.log(newVal);
}, true);
}

}
});


// appController.js
'use strict';

angular.module('tmp')

.controller('appController', ["$scope", function ($scope) {

$scope.sendData = function () {
};

}

]);

// app.html

<submit ng-click="sendData()">
<button class="btn btn-block btn-social btn-google" style="text-align:center;margin-left: auto;margin-right: auto;display: inline-block;" ng-show="{{module == 1}}">
<span class="fa fa-google"></span> Google button
</button>
<button class="btn btn-block btn-social btn-github" style="margin-left: auto;margin-right: auto;text-align:center;display: inline-block;" ng-show="{{module == 2}}">
<span class="fa fa-github"></span> Github button
</button>
<button class="btn btn-block btn-social btn-facebook" style="margin-left: auto;margin-right: auto;text-align:center;display: inline-block;" ng-show="{{module == 3}}">
<span class="fa fa-facebook"></span> Facebook button
</button>
</submit>


Plunker : https://plnkr.co/edit/xBHCDCygCmra62wMGnsM?p=preview

I apologize, I don't know if I made myself clear so if you want more informations, just ask me. Can someone enlighten me please ?

Thank you !

Answer

That's because you change data outside of AngularJS context.

I fixed your plunker here

Your mistakes were:

  • Change data outside AngularJS
  • onClick instead of ng-click
  • 'module': '@' inside directive isolate scope instead of 'module': '='
  • {{ng-show="module == 1}} instead of ng-show="module == 1"

Good luck!

Comments