简体   繁体   中英

Saving an object into an array in a controller in AngularJS

I've been creating a contact list website and have just begun trying to implement an add contact function. So far I have created the page using a form and input elements and then use ng-click to call a function which theoretically would add an object containing these input values into an already-existing array in the controller. For some reason this doesn't work and nothing is added.

In particular, I'm having trouble with the js/app.js file and the $scope.saveContact = function() in relation to the partial/edit.html webpage. Clicking the "Confirm button" when trying to add a contact calls the saveContact function, but the results are not stored properly. Any help is appreciated.

In my HTML I have this code (which calls the saveContact() function in my controller.

<a href="#/"><div class="confirm col-xs-6" ng-click="saveContact()">
    <h3>Confirm</h3>
</div></a>

In my app.js file I have a declaration of an empty object and an array containing objects that already have values (used to display the contacts that are already created). I'm trying to add to these contacts using .push() but it for some reason it doesn't work.

$scope.contact = { ... } //empty object that gets inputs from HTML
$scope.contacts = [ { ... }, ... ];
$scope.saveContact = function(){
    $scope.contacts.push($scope.contact);
};

This bottom function fails to push the contact object to the contacts array and I don't understand why.

This is happening as you have assigned same controller to all your routes. Your saveContact function is working fine, its pushing the object to the array. As soon as the route changes, a new instance of the controller is created and hence the added object is lost. You should create a service(singleton) to store the object and inject the service as a dependency to the controller. In this way the array will persist until the page load.

app.service("storeContact", function(){
  var contacts = [];

  this.setContact = function(cnt){
    contacts.push(cnt)
  };

  this.getContact = function(){
    return contacts;
  }
});

And inject it in the controller and use the setContact and getContact methods to update the contact array and retrieve the contact array.

Ideally, you should have separate controllers for your route.

The issue is in your app.config code. You are using the same controller for all your templates.

This is not required since you have already mentioned the same in ng-controller attached with body

  <body ng-controller="AppController">
    <div ng-view></div>
    <script src="js/app.js"></script>
  </body>

Using same controller for all your routes is essentially (re)instantiating the controllers when the route is changed and thats the reason why $scope.contacts.push($scope.contact); is ineffective for the route / when called from /add .

contactListApp.config(['$routeProvider', '$locationProvider',
  function($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', {
        controller: 'AppController',
        controllerAs: 'list',
        templateUrl: 'partials/list.html'
      })
       .when('/add', {
        controller: 'AppController',
        controllerAs: 'add',
        templateUrl: 'partials/edit.html'
      })
       .when('/edit/:id', {
        controller: 'AppController',
        controllerAs: 'edit',
        templateUrl: 'partials/edit.html'
      })
      .otherwise({
        redirectTo: '/'
      });
}]);

Workaround:

Either use separate controllers for separate routes and use a service to store the object

OR

Simply remove the controller and controller as from your route config and you are good to go.

Updated config:

contactListApp.config(['$routeProvider', '$locationProvider',
  function($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'partials/list.html'
      })
       .when('/add', {
        templateUrl: 'partials/edit.html'
      })
       .when('/edit/:id', {
        templateUrl: 'partials/edit.html'
      })
      .otherwise({
        redirectTo: '/'
      });
}]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM