Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Directives: Change $scope not reflected in UI

I'm trying to making some custom elements with AngularJS's and bind some events to it, then I notice $scope.var won't update UI when used in a binding function.

Here is a simplified example that describing the probelm:

HTML:

<!doctype html> <html ng-app="test">   <head>     <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>     <script src="script.js"></script>    </head>   <body>  <div ng-controller="Ctrl2">   <span>{{result}}</span>   <br />   <button ng-click="a()">A</button>   <button my-button>B</button>  </div>     </body> </html> 

JS:

function Ctrl2($scope) {     $scope.result = 'Click Button to change this string';     $scope.a = function (e) {         $scope.result = 'A';     }     $scope.b = function (e) {         $scope.result = 'B';     } }  var mod = angular.module('test', []);  mod.directive('myButton', function () {     return function (scope, element, attrs) {         //change scope.result from here works         //But not in bind functions         //scope.result = 'B';         element.bind('click', scope.b);     } }); 

DEMO : http://plnkr.co/edit/g3S56xez6Q90mjbFogkL?p=preview

Basicly, I bind click event to my-button and want to change $scope.result when user clicked button B (similar to ng-click:a() on button A). But the view won't update to the new $scope.result if I do this way.

What did I do wrong? Thanks.

like image 554
Mark Ni Avatar asked Apr 17 '13 17:04

Mark Ni


People also ask

What is the difference between $scope and this in AngularJS?

"How does this and $scope work in AngularJS controllers?" When the controller constructor function is called, this is the controller. When a function defined on a $scope object is called, this is the "scope in effect when the function was called". This may (or may not!) be the $scope that the function is defined on.

What does $scope mean in AngularJS?

The $scope in an AngularJS is a built-in object, which contains application data and methods. You can create properties to a $scope object inside a controller function and assign a value or function to it. The $scope is glue between a controller and view (HTML).

Can $scope be injected while creating service?

Explanation: No, the '$scope' cannot be injected while creating service using 'factory' method.

Does AngularJS support scope inheritance?

The $scope object used by views in AngularJS are organized into a hierarchy. There is a root scope, and the $rootScope can has one or more child scopes.


2 Answers

Event handlers are called "outside" Angular, so although your $scope properties will be updated, the view will not update because Angular doesn't know about these changes.

Call $scope.$apply() at the bottom of your event handler. This will cause a digest cycle to run, and Angular will notice the changes you made to the $scope (because of the $watches that Angular set up due to using {{ ... }} in your HTML) and update the view.

like image 133
Mark Rajcok Avatar answered Oct 03 '22 01:10

Mark Rajcok


This might be also a result of different problem but with the same symptoms.

If you destroy a parent scope of the one that is assigned to the view, its changes will not affect the view in any way even after $apply() call. See the example - you can change the view value through the text input, but when you click Destroy parent scope!, model is not updated anymore.

I do not consider this as a bug. It is rather result of too hacky code in application :-)

I faced this problem when using Angular Bootstrap's modal. I tried to open second modal with scope of the first one. Then, I immediately closed the first modal which caused the parent scope to be destroyed.

like image 34
fracz Avatar answered Oct 03 '22 01:10

fracz