1

When I type some string to input element directly, two-way data binding of AngularJS works very well. But when I change value of input element by javascript code, two-way binding does not work. Is there a good way for doing this?

html code:

<div ng-app ng-controller="Ctrl">
    <input id="inputElem" ng-model="modelName" type="text"/>
    <span>{{modelName}}</span>
</div>

javascript code:

function Ctrl($scope) {
    $scope.modelName = "";
}

function foo() {
    // THIS DOES NOT TRIGGER ANGULAR DATA-BINDING!!!!
    $("#inputElem").val("THIS IS DOM MANIPULATION");
}
firia2000
  • 1,773
  • 5
  • 19
  • 20
  • 2
    This not the way you do it in angularjs, instead of changing teh value of the input field you need to change the value of the binded field – Arun P Johny Mar 27 '13 at 11:08

4 Answers4

5

You can achieve this by triggering the change event

$("#inputElem").val("THIS IS DOM MANIPULATION").trigger('change');

Demo: Plunker

Another hack to modify the binded value

var scope = angular.element('#inputElem').scope();
scope.$apply(function(){
  scope.modelName = "THIS IS DOM MANIPULATION";
});

Demo: Plunker

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Thanks! This is exactly what I want! But first code does not work. I think it is because AngularJS does not add any event listener to DOM element. Actually #inputElem had no event listener on 'onchange' when I checked with javascript console. – firia2000 Mar 27 '13 at 13:46
  • 2
    And there is one important notification for second code. For second code working correctly, we need jquery and jquery.js inclusion code() should be placed before inclusion angular.js code in html FYI: http://stackoverflow.com/questions/13480796/error-selectors-not-implemented – firia2000 Mar 27 '13 at 13:53
  • which way are you going to use – Arun P Johny Mar 27 '13 at 13:54
1

You're really supposed to change the model for that rather than the other way around:

http://jsfiddle.net/b9chris/EBWtR/

<div ng-app>
<div ng-controller=Ctrl>
<div><input ng-model=thing /></div>
<div ng-bind=thing></div>
</div>
</div>

function Ctrl($scope) {
    $scope.thing = 'Hi';

    // Later, for some reason you want to change the
    // input in code so you update the model
    setTimeout(function() {
        $scope.thing = 'Bye';
        $scope.$apply();
    }, 2000);
}
Chris Moschini
  • 36,764
  • 19
  • 160
  • 190
0

When you change something outside of angular, you have to call $apply on the $scope, to have your changes applied.

From the docs:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).

http://docs.angularjs.org/api/ng.$rootScope.Scope

Robin Drexler
  • 4,307
  • 3
  • 25
  • 28
0

You can use the ngChange directive for that: http://docs.angularjs.org/api/ng.directive:ngChange

Piet van Dongen
  • 1,629
  • 10
  • 13