I need some help with an ng-model created with ng-bind-html. I have a JSON file in the server in which I have some html and some inputs like this:
*.json
{
"test": {
"1": {
"question":"<span>1. something:</span>",
"options":"<input type='radio' name='q1' ng-model='q.1' value='a'>a) op 1<br><input type='radio' name='q1' ng-model='q.1' value='b'>b) op 2<br><input type='radio' name='q1' ng-model='q.1' value='c'>c) op 3<br><input type='radio' name='q1' ng-model='q.1' value='d'>d) op 4<br><input type='radio' name='q1' ng-model='q.1' value='e'>e) op 5<br>",
"answer":"c"
},
"2": {
...
}
}
}
Then in my HTML file I have something like:
<div class="testContent">
<div class="test">
<div class="questions" ng-repeat="qs in questions" ng-show="questions.length">
<div ng-bind-html="qs.question"></div>
<div class="options" ng-bind-html="qs.options">
</div>
</div>
</div>
<br>
<div class="nextBtn">
<a href="#test/6" class="btn btnNext" ng-click="save()"> continue ></a>
</div>
</div>
And in my Angular controller I have the ajax call for the JSON file:
controller:
.controller('testCtrl', ['$scope', '$http', 'myService', '$sce',
function($scope, $http, myService, $sce, ){
$http.get(urls.url_otis).success(function(data, status){
angular.forEach(data.test, function(value, key){
var q = data.test[key];
q[key] = key;
q.question = $sce.trustAsHtml(q.question);
q.options = $sce.trustAsHtml(q.options);
$scope.questions.push(q);
});
}).error(function(data, status){console.log(status)});
}
The html is populated but I cannot use $watch for the model (q) generated with this approach.
How can I $watch for changes in the models created in this way?
Thanks in advance...
You have to compile dynamically created elements to let angular know about them.
Directive which can do that may look like this one:
app.directive('compile',function($compile, $timeout){
return{
restrict:'A',
link: function(scope,elem,attrs){
$timeout(function(){
$compile(elem.contents())(scope);
});
}
};
});
$timeout
is used to run compile function, after ng-bind-html
do its job.
Now you can just simply put compile
as attribute of div with ng-bind-html
:
<div class="questions" ng-repeat="item in questions" ng-show="questions.length" >
<div ng-bind-html="item.question"></div>
<div compile class="options" ng-bind-html="item.options"></div>
</div>
Fiddle: http://jsfiddle.net/nZ89y/7/
javascript:
app.controller('demoController', function($rootScope, $scope, $http, $compile){
var arr = [
'<div>I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em></div>'
,'<div>name: <input ng-model="user.name" /></div>'
,'<div>age: <input ng-model="user.age" /></div>'];
$scope.user={};
$scope.testChange2 = function(){
var compileFn = $compile( arr[Number.parseInt(Math.random()*10)%3] );
var $dom = compileFn($scope);
$('#test').html($dom);
};
});
html:
<div ng-controller="demoController">
<button type="button" class="btn w-xs btn-info" ng-click="testChange2();" >test2</button>
<hr/>
<div id = "test"></div>
<hr/>
<div>user:{{user}}</div>
来源:https://stackoverflow.com/questions/24560540/how-to-watch-for-ng-model-created-with-ng-bind-html