Search code examples
javascripthtmlangularjsng-options

Changes to ng-options object not updating to html


When I select an item, the input elements update. However, after I save any changes, the element becomes unbound to the ng-model object. Sorry if this is a simple question, I searched for several hours and couldn't figure it out. Thankyou!

HTML

<div ng-app="MyApp" ng-controller="MyController">
  <label>Message Name</label><br>
  <input id="msgName" type="text" value="{{selectedMsg.name}}"><br>

  <label>Load Message</label><br>
  <select id="msgSelect" ng-model="selectedMsg" ng-options="msg.name for msg in Messages"></select><br>

  <label><br>
    Message Text
  </label><br>
  <textarea id="msgText">{{selectedMsg.text}}</textarea><br>
  <button id="saveBtn">SaveMessage</button>

</div>

Javascript

let msg1 = {
  name: "Message 1",
  text: "This is Message 1's text."
}
let msg2 = {
  name: "Message 2",
  text: "This is Message 2's text."
}

let messages = [msg1, msg2];

let app = angular.module('MyApp', []);
app.controller('MyController', function ($scope){
  scope = $scope;
  scope.Messages = messages;
}); 
$('#saveBtn').on('click', () => {
  scope.selectedMsg.name = $('#msgName').val();
  scope.selectedMsg.text = $('#msgText').val();
  scope.$apply();
});

Link to codepen.


Solution

  • First, you don't need the interpolation brackets on the input or textarea. That's what 2-way binding is for and it's ultimately what ng-model does behind the scenes.

    Your comment is correct that you don't need an ng-change in the select either, that's the beauty of reactivity. Here is what your template should look like:

    <select ng-model="selectedMsg" ng-options="msg.name for msg in Messages"></select><br>
    
    <label>Message Name</label><br>
    <input type="text" ng-model="selectedMsg.name"><br>
    
    <label><br>
      Message Text
    </label><br>
    <textarea ng-model="selectedMsg.text"></textarea><br>
    

    You can see that the inputs all share an object model, specifically the textbox and textarea binding to properties of the object selected by the select.

    Working Fiddle