The answer is purely related to the way angular binds data. The simplest answer would be, after manually changing the form data, $scope.$apply() must be called for the element's scope. Called outside the "Angular world" you could change somefnc to:
function somefnc() {
document.getElementById("demo").value = "hi";
$('#demo').scope().$apply();
}
Best practices say that any direct dom manipulation should happen only in directives. Ideally, you would change this value in the controller with something like:
$scope.somefnc = function(){
test.fld = "hi";
}
Anything done through the angular scope like this does not need $scope.$apply, only direct dom manipulation does.
The full example is here
<div ng-controller="AddCtrl">
<input type="text" id="demo" ng-model="test.fld" ng-change="change()"></input>
<br />
[ <a href="" ng-click="somefnc()">pop</a> ]
[ <a href="" ng-click="add(test)">add</a> ]
<p>Test-field: {{test.fld}}</p>
</div>
<script>
angular.module('app').controller('AddCtrl',['$scope',function($scope){
$scope/test = {fld: ''};
$scope.add = function(){
$scope.test.fld += test.fld
}
$scope.change = function(){
alert('I changed!');
}
$scope.somefnc = function() {
$scope.test.fld = "hi";
}
}])
</script>