简体   繁体   中英

Update an Array of Objects Using Form - AngularJS

I have a form with 3 inputs, which the user will insert the hex value for colors.

I need to receive these values and to update one property of objects of an Array. This update will be just for front-end purpose, no Json access or server is running.

Form.html

<form name="colorform" class="row col-md-offset-1" ng-submit="update(name, data)">
    <div class="col-md-6">
        <div class="form-group">
            <label>Color A</label>
            <input name="main" ng-model="colors.main" class="form-control">    
        </div>
        <div class="form-group">
            <label>Color B</label>
            <input name="locker" ng-model="colors.locker" class="form-control">    
        </div>
        <div class="form-group">
            <label>Color C</label>
            <input name="path" ng-model="colors.path" class="form-control">    
        </div>

        <button type="submit" class="btn btn-primary">
            Save
        </button>
         <a href="#/" class="btn btn-primary">Back</a>
        <hr>
    </div>
</form>

The Array of Objects:

$scope.colors = [
        {name: "main", color: "white"},
        {name: "locker", color: "black"},
        {name: "path", color: "yellow"}
    ];

And the update function:

$scope.update = function(name, data) {
   for (var i = 0; i < $scope.colors.length; i++) {
       if ($scope.colors[i].name == name) {
           $scope.colors[i].color = data;
           break;
       }
   }
 }

I intent to update the color property. The goal is to reflect in a html element, that uses this function on Controller:

$scope.style = function ($index) {       
        return {
            "height" : "15px",
            "width" : "15px",
            "border" : "1px solid #CCC",
            "background-color": $scope.colors[1].color,
            "float": "left"
        }
    }

And on HTML that displays:

<div ng-style="boardStyle" class="board">
  <div ng-repeat="tile in getNumber(tiles) track by $index" 
    ng-style="style($index)"></div>
</div>

But... Nothing happens. Where am I doing wrong?

I think we can improve your code a bit, first problem you have is that your input models point to wrong thing. Let's create good model for your data:

$scope.colors = {
    main: {
      color: "white"
    },
    locker: {
      color: "black"
    },
    path: {
      color: "yellow"
    }
  };

After this let's fix your getNumber function to return keys of an object in array:

$scope.getNumber = function(tiles){
  return Object.keys($scope.colors);
}

and at the end fix your style function to take key and not $index, which is very bad in my opinion, so:

$scope.style = function (key) {       
        return {
            "height" : "15px",
            "width" : "15px",
            "border" : "1px solid #CCC",
            "background-color": $scope.colors[key].color,
            "float": "left"
        }
    }

And at the end we need to do some small changes in html to adjust few things in your code like input fields pointing to correct model:

<input name="main" ng-model="colors.main.color" class="form-control">
<input name="locker" ng-model="colors.locker.color" class="form-control">
<input name="path" ng-model="colors.path.color" class="form-control">

and repeat divs:

<div ng-repeat="tile in getNumber(tiles) track by $index" ng-style="style(tile)"></div>

If you decide you actually want functionality of save button to trigger change, you can just duplicate colors object and just name it $scope.colors2 - change ng-model on inputs to point to colors2 and inside your update function just update colors with colors2 $scope.colors = $scope.colors2

Here's fiddle to show how it works:

https://jsfiddle.net/pegla/j392Lvdp/5/

Also here's fiddle with save button working:

https://jsfiddle.net/pegla/j392Lvdp/6/

If you don't have any work with the server. You don't really need a form/submit() to update properties. You are using ng-model to access array of object which automatically updates the properties.

   <form name="colorform" class="row col-md-offset-1" ng-submit="update()">
    <div class="col-md-6">
        <div class="form-group">
            <label>Color A</label>
            <input name="main" ng-model="colors[0].color" class="form-control">    
        </div>
        <div class="form-group">
            <label>Color B</label>
            <input name="locker" ng-model="colors[1].color" class="form-control">    
        </div>
        <div class="form-group">
            <label>Color C</label>
            <input name="path" ng-model="colors[2].color" class="form-control">    
        </div>

        <button type="submit" class="btn btn-primary">
            Save
        </button>
         <a href="#/" class="btn btn-primary">Back</a>
        <hr>
    </div>
</form>

<div>
  <div ng-repeat="tile in colors track by $index" ng-style="style($index)"></div>
</div>

Here is your array of objects just as you need:

  $scope.colors = [
        {name: "main", color: "white"},
        {name: "locker", color: "black"},
        {name: "path", color: "yellow"}
    ];

Your update function if want one:

  $scope.update = function() {
    alert("Colors have been updated!");
  }

And your style function:

  $scope.style = function(key) {
    return {
      "height": "15px",
      "width": "15px",
      "border": "1px solid #CCC",
      "background-color": $scope.colors[key].color,
      "float": "left"
    }
  }    

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