Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

online code:

http://jsfiddle.net/mb98y/309/

HTML

<div ng-app="myDirective" ng-controller="x">
    <input id="angular" type="text" ng-model="data.test" my-directive>
</div>
    <button onclick="document.querySelector('#angular').value = 'testg';">click</button>

JS

angular.module('myDirective', [])
    .directive('myDirective', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            scope.$watch(attrs.ngModel, function (v) {
                //console.log('value changed, new value is: ' + v);
                alert('value change: ' + scope.data.test);
            });
        }
    };
});

function x($scope) {
    //$scope.test = 'value here';
    $scope.data = {
        test: 'value here'
    }
}

http://jsfiddle.net/mb98y/310/

HTML

<div ng-app="myDirective" ng-controller="x">
<input id="angular" type="text" my-directive="test">{{test}}</div>
<button onclick="document.querySelector('#angular').value =  'testg';">click</button>

JS

angular.module('myDirective', [])
    .directive('myDirective', function () {
    return {
        restrict: 'A',
        scope: {
            myDirective: '='
        },
        link: function (scope, element, attrs) {
            // set the initial value of the textbox
            element.val(scope.myDirective);
            element.data('old-value', scope.myDirective);

            // detect outside changes and update our input
            scope.$watch('myDirective', function (val) {
                element.val(scope.myDirective);
            });

            // on blur, update the value in scope
            element.bind('propertychange keyup change paste', function (blurEvent) {
                if (element.data('old-value') != element.val()) {
                    console.log('value changed, new value is: ' + element.val());
                    scope.$apply(function () {
                        scope.myDirective = element.val();
                        element.data('old-value', element.val());
                    });
                }
            });
        }
    };
});

function x($scope) {
    $scope.test = 'value here';
}

I wanna click button to set input element value and angularjs(ng-model or scope object) can get it.

But, document.querySelector('#angular').value = 'testg';

change element value in this way, Neither angularjs $watch nor bind function can get value change event. If you input some words in input element by keyboard, they both works.

How can I detect input element value change when set value in this way in angularjs?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

First of all, binding is here in order to avoid such scenarios.

 <input ng-model='ctrl.field' />

 <button ng-click='ctrl.field = "new value"'>change</button>

Second, there is ng-change directive that works together with ng-model, which can be used to do something when value in the model changed.

 <input ng-model='ctrl.field' ng-change='alert("changed!")' />

If you still want to change value outside of angular directly with DOM, just fire event that angular listen to - blur or keypressed

 <button ng-click='$("#id").val(a); $("#id").trigger("blur")'>change</button>

or

 <button ng-click='angular.element("#id").val(a); angular.element("#id").trigger("blur")'>change</button>
share|improve this answer
    
Good idea for me, the second method fire event works. I followed your suggestion without jquery. Thank you! –  Gino May 26 '14 at 2:47
    
@Gino Angular expose jQuery-lite anyway, so you totally can do it with jquery. –  vittore May 26 '14 at 11:48

Updated fiddle.

You are not supposed to use querySelector (just like you are not supposed to use jQuery) with Angular, unless you have a real good reason to.

You can just modify $scope.data.test, and your text box contents will be updated automatically. In order for this to work, you also need the button to have the same controller (so they share scope), and use ng-click instead of onclick, like so:

<div ng-app="myDirective" ng-controller="x">
    <input id="angular" type="text" ng-model="data.test" my-directive=""></input>
    <button ng-click="data.test = 'testg';">click</button>
</div>
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.