silvesterprabu
silvesterprabu

Reputation: 1457

Scope not updating on click

This is my html

 <div ng-controller="data">
       <div class="main">
           <div>{{name}}</div>
           <div custom-tag>click</div>
       </div></br>
       <div class="main">
           <div>{{name}}</div>
           <div custom-tag>click</div>
       </div></br>
       <div class="main">
           <div>{{name}}</div>
           <div custom-tag>click</div>
       </div>
 </div>

When i click on particular div (click div) , I want to chage the name into above div of the particular clicked div .

This is my controller

 app.controller('data',function($scope)
 {
     $scope.name="john"

 });

So when I load my html page it will be shown like this

 John
 click

 john
 click

 john
 click

When I click on first click , I have to change name to britto so out put should be like this

 Britto 
 click

 john
 click

 john
 click

This is my directive i have tried like this. When I click on div I am getting alert message that clicked . But scope is not changed the name

 app.directive('customTag',function()
{
       return function(scope, element, attrs)
       {
         element.bind('click',function()
         {
           alert("clicked");
           scope.name="britto"

         });
       }

});

Upvotes: 2

Views: 107

Answers (2)

oori
oori

Reputation: 5701

Quick answer: You have to call scope.$apply() after you change the scope, as the "click" isn't "angular-aware".

It'll work, but there are much better way to do what you're after:
A. Use ng-click, and skip the directive

<div>{{name}}</div>
<div ng-click="changeName()">click</div>

Then add to your controller:

$scope.changeName = function(){ $scope.name="britto"; }

B. Directives and scopes: You should really take the time and read through this documentation page
You can jump directly to: "Isolating the Scope of a Directive" section

---- (EDIT) ----
C. Using ng-repeat

controller:

$scope.names = ["john","michael","jack"];

html:

<div ng-controller="data">
   <div class="main" ng-repeat="name in names">
       <div>{{name}}</div>
       <div ng-click="name='britto'">click</div>
       <br/>
   </div>
</div>

See this plunkr

Upvotes: 0

iConnor
iConnor

Reputation: 20209

You need to tell the scope that you made changes, seeing as you're updating the scope outside of angular.

Like this.

element.bind('click',function(){
   alert("clicked");
   scope.name = "britto"
   scope.$apply();
});

You can also do this.

element.bind('click',function(){
   alert("clicked");
   scope.$apply(function() {
      scope.name = "britto"
   });
});

I'm not entirely sure what the difference is...

A good way to help remember this is to remember that any function that is not called by angular.js and is out of the program flow you need to use scope.$apply(); whenever making changes to the scope, so click would be out of the flow because it can be triggered at any time.

Upvotes: 4

Related Questions