The ng-change event does not fire inside a loop

function friendControllerTest($scope, $http) { $scope.loading = true; $scope.addMode = false; $scope.countryList = []; $scope.stateList = []; function getAllCountry() { $http({ method: 'Get', url: '/Home/GetCountry' }).success(function (data) { $scope.countryList = data; }).error(function () { $scope.errorMessage = 'Not found'; }); } function getStatebyCountryId(Id) { $scope.stateList = null; if (Id) { // Check here country Id is null or not $http({ method: 'POST', url: '/Home/GetStateByCountryId/', data: JSON.stringify({ CountryId:Id }) }).success(function (data) { $scope.stateList = data; }).error(function (data) { alert(data.message); $scope.message = 'not found'; }); } else { $scope.stateList = null; } } $scope.GetStatesList = function (id) { if (id) { // Check here country Id is null or not $http({ method: 'POST', url: '/Home/GetStateByCountryId/', data: JSON.stringify({ CountryId: id }) }).success(function (data) { $scope.stateList = data; }).error(function (data) { alert(data.message); $scope.message = 'not found'; }); } else { $scope.stateList = null; } } $scope.myMethod = function () { var text = $scope.newfriend.SearchText; $http.get('../Home/GetFriendsList', { params: { 'text': text } }).success(function (data) { $scope.friends = data; }) .error(function () { $scope.error = "An Error has occured while loading posts!"; }); } $http.get('../Home/GetFriendsList').success(function (data) { alert("list called") $scope.friends = data; $scope.loading = false; }) .error(function () { $scope.error = "An Error has occured while loading posts!"; $scope.loading = false; }); $scope.toggleAdd = function () { $scope.addMode = !$scope.addMode; if ($scope.addMode) { getAllCountry(); } }; $scope.toggleEdit = function () { this.friend.editMode = !this.friend.editMode; getAllCountry(); if (this.friend.Country.Id > 0) getStatebyCountryId(this.friend.Country.Id); }; $scope.add = function () { $scope.loading = true; var newfriend = { firstname: $scope.newfriend.firstname, lastname: $scope.newfriend.lastName, address: $scope.newfriend.address, postalcode: $scope.newfriend.PostalCode, notes: $scope.newfriend.Notes, CountryId: $scope.newfriend.Country.Id, StateId: $scope.newfriend.State.Id } $http.post('../Home/AddFriends', newfriend).success(function (data) { alert("Added Successfully!!"); $scope.addMode = false; $scope.friends.push(data); $scope.loading = false; $scope.newfriend = ""; }).error(function (data) { $scope.error = "An Error has occured while Adding Friend! " + data; $scope.loading = false; }); }; $scope.save = function () { $scope.loading = true; var frien = this.friend; $http.put('../Home/EditFriend', frien).success(function (data) { alert("Saved Successfully!!"); frien.editMode = false; $scope.loading = false; }).error(function (data) { $scope.error = "An Error has occured while Saving Friend! " + data; $scope.loading = false; }); }; $scope.deletefriend = function () { $scope.loading = true; var friendid = this.friend.Id; $http.delete('../Home/RemoveFriend/' + friendid).success(function (data) { alert("Deleted Successfully!!"); $.each($scope.friends, function (i) { if ($scope.friends[i].Id === friendid) { $scope.friends.splice(i, 1); return false; } }); $scope.loading = false; }).error(function (data) { $scope.error = "An Error has occured while Saving Friend! " + data; $scope.loading = false; }); }; } 
 <html data-ng-app="" data-ng-controller="friendControllerTest"> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="container"> <strong class="error">{{ error }}</strong> <div id="mydiv" data-ng-show="loading"> <img src="Images/ajax-loader1.gif" class="ajax-loader" /> </div> <p data-ng-hide="addMode"> <a data-ng-click="toggleAdd()" href="javascript:;" class="btn btn-primary">Add New </a> </p> <form name="addFriend" data-ng-show="addMode" style="width: 600px; margin: 0px auto;"> <label>FirstName:</label><input type="text" data-ng-model="newfriend.firstname" required /> <label>LastName:</label><input type="text" data-ng-model="newfriend.lastName" required /> <label>Address:</label><input type="text" data-ng-model="newfriend.address" required /> <label>Country:</label> <select ng-model="newfriend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="GetStatesList(newfriend.Country.Id)"> <option value="">Select Country</option> </select> <label>State:</label> <select ng-model="newfriend.State" ng-options="s.Name for s in stateList track by s.Id"> <option value="">Select State</option> </select> <label>PostalCode:</label><input type="text" data-ng-model="newfriend.PostalCode" required /> <label>Notes:</label><input type="text" data-ng-model="newfriend.Notes" required /> <br /> <br /> <input type="submit" value="Add" data-ng-click="add()" data-ng-disabled="!addFriend.$valid" class="btn btn-primary" /> <input type="button" value="Cancel" data-ng-click="toggleAdd()" class="btn btn-primary" /> <br /> <br /> </form> <table class="table table-bordered table-hover" style="width: 800px"> <tr> <th>#</th> <td>FirstName</td> <th>LastName</th> <th>Address</th> <th>Country</th> <th>State</th> <th>PostalCode</th> <th>Notes</th> </tr> <tr data-ng-repeat="friend in friends"> <td><strong>{{ friend.Id }}</strong></td> <td> <p data-ng-hide="friend.editMode">{{ friend.firstname}}</p> <input data-ng-show="friend.editMode" type="text" data-ng-model="friend.firstname" /> </td> <td> <p data-ng-hide="friend.editMode">{{ friend.lastname }}</p> <input data-ng-show="friend.editMode" type="text" data-ng-model="friend.lastname" /> </td> <td> <p data-ng-hide="friend.editMode">{{ friend.address }}</p> <input data-ng-show="friend.editMode" type="text" data-ng-model="friend.address" /> </td> <td> <p data-ng-hide="friend.editMode">{{ friend.Country.Name }}</p> <select data-ng-show="friend.editMode" ng-model="friend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="$parent.GetStatesList(friend.Country.Id)"> <option value="">Select Country</option> </select> </td> <td> <p data-ng-hide="friend.editMode">{{friend.State.Name }}</p> <select data-ng-show="friend.editMode" ng-model="friend.State" ng-options="s.Name for s in stateList track by s.Id"> <option value="">Select State</option> </select> </td> <td> <p data-ng-hide="friend.editMode">{{ friend.postalcode }}</p> <input data-ng-show="friend.editMode" type="text" data-ng-model="friend.postalcode" /> </td> <td> <p data-ng-hide="friend.editMode">{{ friend.notes }}</p> <input data-ng-show="friend.editMode" type="text" data-ng-model="friend.notes" /> </td> <td> <p data-ng-hide="friend.editMode"><a data-ng-click="toggleEdit(friend)" href="javascript:;">Edit</a> | <a data-ng-click="deletefriend(friend)" href="javascript:;">Delete</a></p> <p data-ng-show="friend.editMode"><a data-ng-click="save(friend)" href="javascript:;">Save</a> | <a data-ng-click="toggleEdit(friend)" href="javascript:;">Cancel</a></p> </td> </tr> </table> <hr /> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/angularjs") <script src="~/Scripts/MyScript.js"></script> </body> 

I’m trying to open the "Country and State" drop-down list in edit mode, and so far I’m sure of it.

But the only problem is that when I click on any entry that needs to be opened in edit mode, the drop-down menu of my country and state is attached correctly, but when I select another country from the drop-down list of the country, then my ng-change does not work, and I don’t want to know why.

This is my view on adding a new entry :

 <select ng-model="newfriend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="GetStatesList()"> <option value="">Select Country</option> </select> <label>State:</label> <select ng-model="newfriend.State" ng-options="s.Name for s in stateList track by s.Id"> <option value="">Select State</option> </select> 

My controller :

  function friendControllerTest($scope, $http) { $scope.GetStatesList = function () { //server side call to fetch state by country id } $scope.toggleEdit = function () { this.friend.editMode = !this.friend.editMode; getAllCountry(); if (this.friend.Country.Id > 0) getStatebyCountryId(this.friend.Country.Id); }; }; 

My record viewing screen :

 <table class="table table-bordered table-hover" style="width: 800px"> <tr data-ng-repeat="friend in friends"> <td> <p data-ng-hide="friend.editMode">{{ friend.Country.Name }}</p> <select data-ng-show="friend.editMode" ng-model="friend.Country" ng-options="c.Name for c in countryList track by c.Id" ng-change="GetStatesList()"> <option value="">Select Country</option> </select> </td> <td> <p data-ng-hide="friend.editMode">{{friend.State.Name }}</p> <select data-ng-show="friend.editMode" ng-model="friend.State" ng-options="s.Name for s in stateList track by s.Id"> <option value="">Select State</option> </select> </td> </tr> <table> public class HomeController : Controller { // // GET: /Home/ private FriendsEntities db = new FriendsEntities(); public ActionResult Index() { return View(); } public ActionResult GetFriendsList(string text) { var data = db.Friends.Select ( d => new FriendModel { Id=d.Id, firstname = d.firstname, lastname = d.lastname, address = d.address, notes = d.notes, postalcode = d.postalcode, Country = d.Country.Friends.Select ( x => new CountryModel { Id=x.Country.Id, Name = x.Country.Name } ).FirstOrDefault(), State = d.State.Friends.Select ( s => new StateModel { Id=s.State.Id, Name = s.State.Name } ).FirstOrDefault() } ).ToList(); return Json(data, JsonRequestBehavior.AllowGet); } [HttpPost] public ActionResult AddFriends(Friends FriendsModel) { var result = db.Friends.Add(FriendsModel); db.SaveChanges(); var data = db.Friends.Where(t => t.Id == result.Id).Select ( d => new FriendModel { Id=d.Id, firstname = d.firstname, lastname = d.lastname, address = d.address, notes = d.notes, postalcode = d.postalcode, Country = d.Country.Friends.Select ( x => new CountryModel { Id=x.Country.Id, Name = x.Country.Name } ).FirstOrDefault(), State = d.State.Friends.Select ( b => new StateModel { Id=b.State.Id, Name = b.State.Name } ).FirstOrDefault() } ).SingleOrDefault(); return Json(data); } public ActionResult RemoveFriend(int id) { Friends friend = db.Friends.Find(id); db.Friends.Remove(friend); db.SaveChanges(); return Json(friend); } public JsonResult GetCountryState() { List<CountryModel> Country = new List<CountryModel>().ToList(); Country.Add(new CountryModel() { Id = 0, Name = "Select Country" }); var Data = db.Country.Select ( d => new CountryModel { Id = d.Id, Name = d.Name, State = d.State.Select ( x => new StateModel { Id = x.Id, Name = x.Name } ).ToList() } ).ToList(); Country.AddRange(Data); return Json(Country, JsonRequestBehavior.AllowGet); } public JsonResult GetCountry() { var Data = db.Country.Select ( d => new CountryModel { Id = d.Id, Name = d.Name, } ).ToList(); return Json(Data, JsonRequestBehavior.AllowGet); } public JsonResult GetStateByCountryId(int CountryId) { var getStateList = db.State.Where(p => p.CountryId == CountryId).Select(x => new { x.Id, x.Name }).ToList(); return Json(getStateList, JsonRequestBehavior.AllowGet); } [HttpPut] public ActionResult EditFriend(Friends FriendModel) { Friends friend = db.Friends.Find(FriendModel.Id); friend.firstname = FriendModel.firstname; friend.lastname = FriendModel.lastname; friend.postalcode = FriendModel.postalcode; friend.notes = FriendModel.notes; friend.address = FriendModel.address; friend.CountryId = FriendModel.Country.Id; friend.StateId = FriendModel.State.Id; db.SaveChanges(); var friendModel = new FriendModel(); friendModel.Id = friend.Id; friendModel.firstname = friend.firstname; friendModel.lastname = friend.lastname; friendModel.postalcode = friend.postalcode; friendModel.notes = friend.notes; friendModel.address = friend.address; friendModel.CountryId = friend.CountryId; friendModel.StateId = friend.StateId; return Json(friendModel); } } public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js")); bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.validate*")); // Use the development version of Modernizr to develop with and learn from. Then, when you're // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( "~/Scripts/modernizr-*")); bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/Scripts/bootstrap.js", "~/Scripts/respond.js")); bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/bootstrap.css", "~/Content/site.css")); bundles.Add(new ScriptBundle("~/bundles/angularjs").Include( "~/Scripts/angular.min.js")); bundles.Add(new ScriptBundle("~/bundles/appjs").Include( "~/Scripts/app/customerCtrl.js")); } } 
+5
source share
2 answers

Your problem is that you are accessing the scope inside ng-repeat and directives like ng-repeat , ng-switch , ng-view , ng-include & ng-if create a new scope in the current workspace. To access a method or variable in the parent scope, you need to use $parent , which provides access to the parent

First you need to read Understanding Angular Inheritance Scale .

Plunkr for clarification of the same.

Below is the only change that is required in your markup

 ng-change="GetStatesList()" 

to

 ng-change="$parent.GetStatesList()" 

Hope this helps you, thanks.

+5
source

ng-change event doesn't fire in Angularjs

You have two kinds.

  1. Add record( give info to country ,state) 2. Display stored records (with edit mode to change country,state) 

In the record entry window, ng-change="GetStatesList()" starts and displays a list of states, calling GetStatesList() function friendControllerTest when the country is selected (model value changed).

Your View Records view has its own controller. It does not have the GetStatesList() function, so ng-change does not work.

Two solutions to this problem:

  1. Make "$scope.GetStatesList()" to "$rootScope.GetStatesList()"- rootscope 2. Write service/factory method then you can use wherever you want. 

EDIT: but using $parent.GetStateList() is good practice like @pankajparkar soltution

+2
source

Source: https://habr.com/ru/post/1215731/


All Articles