问题
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...
回答1:
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/
回答2:
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