Angularjs - Why I can update an object but not the list (ng-repeat) from a different view?
-
22-12-2019 - |
Question
By the console the customers object seems updated, but the list(ng-repeat) not, what can i do. If I implement this funciont and view2.htm's html inside page.htm it works.
HTML "page.htm"
<body ng-controller="simpleController">
<div ng-view></div>
<input ng-model="cust" type="text" />
<ul><li ng-repeat="cust in customers | filter:cust ">{{cust.name}} - {{cust.city}}</li></ul>
<label for="_newname">Customer name:</label>
<input name="_newname" ng-model="_newname" type="text" />
HTML "view2.htm"
<label for="newname">Customer name:</label>
<input name="newname" ng-model="newname" type="text" />
<label for="newcity">Customer city:</label>
<input name="newcity" ng-model="newcity" type="text" />
<button ng-click="addNewCustomer()" >Add Customer</button>
Jvascript
var demoApp = angular.module("demoApp", ["ngRoute"]);
demoApp.controller("simpleController", simpleController);
function simpleController($scope){
$scope.customers = [
{name : "Fulvio", city:"London" },
{name : "Elisa", city:"Catanzaro" },
{name : "Immacolata", city:"Catanzaro"},
{name : "Vitaliano", city:"Roma"},
{name : "Ivan", city:"Milano"}
];
$scope.addNewCustomer = addNewCustomer.bind($scope);
}
demoApp.config(function($routeProvider){
$routeProvider.
when("/",{
controller: simpleController,
templateUrl: "view2.htm",
}).
when("/second",{
controller: simpleController,
templateUrl: "view2.htm"
}).
when("/third",{
controller: simpleController,
templateUrl: "view3.htm"
}).
otherwise({redirectTo: "/"});
});
var addNewCustomer = function(){
this.customers.push({name:this.newname, city:this.newcity});
}
Solution
Unlike services, which are singletons, controllers are created freshly each time.
<body ng-controller="simpleController">
creates a controller with a scope, that is used by your ng-repeat
directive.
when("/",{controller: simpleController,
creates yet another controller with its own scope and its own customers
list, that you are adding to when the button is clicked. It's not the same list as in the parent controller.
I assume you want to use only one simpleController
so don't add one to your routing definitions.
$routeProvider.
when("/",{
// controller: simpleController, <- don't do this
templateUrl: "view2.htm",
}).
But you have something else to keep in mind: The way you define you ng-model
sticks it to the scope of the view. The cleanest way imho is to write a separate controller for each view, that deals only with the view. That's the way it's meant to be, because addNewCustomer
is only relevant for that view.
demoApp.controller('viewController', function($scope) {
$scope.addNewCustomer = function(){
$scope.customers.push({name:$scope.newname, city:$scope.newcity});
}
})
when("/",{
controller: viewController,
templateUrl: "view2.htm",
}).
OTHER TIPS
try adding this.apply() to your addNewCustomer method...
I solved the problem using $rootScope Html
<button ng-click="$broadcast('addNewCustomer')" >Add Customer</button>
Javascript
function simpleController($rootScope, $scope){
$rootScope.customers = [
{name : "Fulvio", city:"London" },
{name : "Elisa", city:"Catanzaro" },
{name : "Immacolata", city:"Catanzaro"},
{name : "Vitaliano", city:"Roma"},
{name : "Ivan", city:"Milano"}
];
$scope.$on("addNewCustomer", function(){
$scope.customers.push({name: $scope.newname, city: $scope.newcity});
console.log( $rootScope.customers );
});
}
Try something like this. I remade your controller so that the addNewCustomer function is within the same controller.
var demoApp = angular.module("demoApp", ["ngRoute"]);
demoApp.controller("simpleController" function($scope) {
$scope.customers = [
{name : "Fulvio", city:"London" },
{name : "Elisa", city:"Catanzaro" },
{name : "Immacolata", city:"Catanzaro"},
{name : "Vitaliano", city:"Roma"},
{name : "Ivan", city:"Milano"}
];
// You can do two things here, either pass in the customer object,
// OR bind to $scope.customer on your model
$scope.addNewCustomer = function(customer){
$scope.customers.push(customer);
};
});
demoApp.config(function($routeProvider){
$routeProvider.
when("/",{
controller: simpleController,
templateUrl: "view2.htm",
}).
when("/second",{
controller: simpleController,
templateUrl: "view2.htm"
}).
when("/third",{
controller: simpleController,
templateUrl: "view3.htm"
}).
otherwise({redirectTo: "/"});
});
** Views
page.html
<!-- not sure what this input is for -->
<input ng-model="customer" type="text">
<ul>
<li ng-repeat="cust in customers | filter:cust ">
{{cust.name}} - {{cust.city}}
</li>
</ul>
<label for="_newname">Customer name:</label>
<input name="_newname" ng-model="_newname" type="text">
view2.html
<label for="newname" >Customer name:</label>
<input name="newname" ng-model="customer.name" type="text">
<label for="newcity">Customer city:</label>
<input name="newcity" ng-model="customer.city" type="text">
<button ng-click="addNewCustomer(customer)" >Add Customer</button>