0

Why does changing the value in a textarea break the binding? Allow myVal to update to say Hello, but then if typing anything else, then clicking the button no longer updates the value.

html

<!doctype html>
<html ng-app="app">
<head>
</head>
<body>

  <div ng-controller="Ctrl">
  <textarea ng-bind="formModel.myVal"></textarea>
  <button ng-click="update()">Update</button>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
  <script src="script.js"></script>
</body>
</html>

js

var app = angular.module('app', []);

app.controller('Ctrl', function($scope, $timeout) {
 $scope.formModel = {};

 $timeout(function() {
   $scope.formModel.myVal = 'Hello';
 }, 1000);

 $scope.update = function() {
   $scope.formModel.myVal = 'Bye';
 };
});    

Edit:

To clarify; I want one-way binding which is what ng-bind provides. I am wondering why changing the value in textarea breaks this one way binding. I would expect this if I had tried to bind directly to a string, but the binding is to an object property.

tic
  • 2,484
  • 1
  • 21
  • 33
  • Use `ng-model`=> `` – Rayon Jan 12 '16 at 05:03
  • @RayonDabre I don't want 2 way binding – tic Jan 12 '16 at 05:04
  • you are asking about a feature of two way binding, yet in your comments say you don't want two way binding. This doesn't make sense. – Claies Jan 12 '16 at 05:05
  • @Claies, `ng-bind` will be `controller to view` then what OP is asking makes sense right ? – Rayon Jan 12 '16 at 05:06
  • @Claies I want one way binding. I am asking why changing the value in the textarea breaks the binding – tic Jan 12 '16 at 05:07
  • This doesn't make any sense at all. You can't one way bind inputs. When you change the value in an input box, that value has to be stored in the DOM somewhere. if you are using `ng-bind`, which doesn't create a binding back to the JavaScript (a watch to update the JS variable with the typed value), then the moment you change the value, you are replacing the bound element with the typed value. Besides that, why provide an input at all if you don't want your users to change the value? – Claies Jan 12 '16 at 05:11
  • @Claies I don't know about it making no sense at all. If you want all the styling and behaviour of a textarea with a given class, and don't want to have to recreate that in css and code. Especially as it is not obviously mentioned anywhere I can find in the documentation that you can't use ng-bind on a textarea – tic Jan 12 '16 at 05:19
  • what you are trying to do by rewriting the textbox on `$interval` is hackish at best. not only does it create more work for your site for little purpose, it also would be confusing to the user who is attempting to type and has the box reset mid typing. sure, they may get used to the idea that even though that *looks* like they can type there, they really can't, but more likely, it will create phone calls about why your website is broken and won't let them finish typing. It just doesn't make sense in terms of what a textarea is intended for. – Claies Jan 12 '16 at 05:26
  • However, you are correct that the documentation isn't exactly clear about the usage for ng-bind, and it could probably use an update. I know I read an article at some point discussing the difference between `ng-bind` and `ng-model`, I just can't find it at the moment. – Claies Jan 12 '16 at 05:29
  • I don't want to overly go into justifying this, but it is for an internal application that users are using for copying from to then use for data entry. I want the ability to resize the textarea easily, as well as the styling and everything that already exists. I can (and do) disable the textareas so they can't type and break the binding, but I also would ideally like to fix it in code also. – tic Jan 12 '16 at 05:32
  • I apologize, I don't mean to be overly critical; This is just a very abnormal kind of problem that wouldn't apply to most people. I'm trying to think of a way that something could be written that accomplishes your goal; the only thing I can think of is instead of using `$interval`, use `ng-model` (even though it's not what you really want), and create a `$watch` that resets the value if it changes. You can even add a debounce using `ng-model-options` so that it doesn't reset too often, (like every keystroke). – Claies Jan 12 '16 at 05:42

2 Answers2

0

Update Your code

ng-model was missing

use ngBind when your scope is already bind to your html, use ngModel when insert data and also you changes in your binded data that time you can also use.

<!doctype html>
<html ng-app="app" ng-controller="Ctrl">
<head>
</head>
<body>
    <div>
        <textarea ng-model="formModel.myVal" ></textarea>
        <button ng-click="update()">Update</button>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
    <script>

        var app = angular.module('app', []);

        app.controller('Ctrl', function ($scope, $timeout) {
            $scope.formModel = {};

                $scope.formModel.myVal = 'Hello';

            $scope.update = function () {
                $scope.formModel.myVal = 'Bye';
            };
        });

    </script>
</body>
</html>
Maher
  • 2,517
  • 1
  • 19
  • 32
0

you can use ng-model so, you'll make it update and when you call function then you'll also get your set value.

var app = angular.module('app', []);

app.controller('Ctrl', function($scope, $timeout) {
 $scope.formModel = {};

 $timeout(function() {
   $scope.formModel.myVal = 'Hello';
 }, 1000);

 $scope.update = function() {
   $scope.formModel.myVal = 'Bye';
 };
});
<!doctype html>
<html ng-app="app">
<head>
</head>
<body>

  <div ng-controller="Ctrl">
  <textarea ng-model="formModel.myVal"></textarea> 
  <button ng-click="update()">Update</button>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
  <script src="script.js"></script>
</body>
</html>