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});
}
Was it helpful?

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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top