This problem happened to me without applying the ng-if directive to elements surrounding the textarea element. Although Matthew's decision is correct, the reason seems different. A search for this problem points to this message, so I decided to share this.
If you look at the AngularJS documentation here https://docs.angularjs.org/api/ng/directive/textarea , you will see that Angular adds its own directive called <textarea> , which "overrides" the default HTML textarea element. This is a new area that is causing the whole mess.
If you have a variable like
$scope.myText = 'Dummy text';
in your controller and bind it to a textarea element like this
<textarea ng-model="myText"></textarea>
AngularJS will look for this variable in the scope of the directive. It is not, and therefore it approaches $ parent. The variable is present there, and the text is inserted into textarea . When changing text in textarea , Angular does NOT change the parent variable. Instead, it creates a new variable in the scope of the directive and, therefore, the original variable is not updated. If you bind textarea to the parent variable, as suggested by Matthew, Angular will always bind to the correct variable, and the problem will disappear.
<textarea ng-model="$parent.myText"></textarea>
I hope this clarifies the situation for other people coming to this question and think: "WTF, I do not use ng-if or any other directive in my case!" as I did when I first landed here;)
Update: use controller syntax -
I wanted to add this long before that, but I did not find time for this. This is a modern style of building controllers and should be used instead of the above $parent . Read on to find out how and why.
Since AngularJS 1.2 allows you to refer to the controller object directly, instead of using the $scope object. This can be achieved using this syntax in the HTML markup:
<div ng-controller="MyController as myc"> [...] </div>
Popular routing modules (such as the UI Router) provide similar properties for their states. For the UI Router, you use the following in determining your status:
[...] controller: "MyController", controllerAs: "myc", [...]
This helps us bypass the problem with nested or incorrectly addressed areas. The above example will be constructed in this way. The first part is JavaScript. Right ahead, you just donβt use the $scope link to set your text, just use this to attach the property directly to the controller object.
angular.module('myApp').controller('MyController', function () { this.myText = 'Dummy text'; });
The markup for textarea with controller-as syntax would look like this:
<textarea ng-model="myc.myText"></textarea>
This is the most effective way to do such things today, because it solves the problem using nested areas, forcing us to calculate how many layers we are at a certain point. Using several nested directives inside elements with the ng-controller directive could lead to something similar when using the old method of referencing areas. And nobody wants to do this all day!
<textarea ng-model="$parent.$parent.$parent.$parent.myText"></textarea>