#angularjs #watch #ng-bind-html
#angularjs #Смотреть #ng-bind-html
Вопрос:
Мне нужна некоторая помощь с ng-моделью, созданной с помощью ng-bind-html. У меня есть файл JSON на сервере, в котором у меня есть некоторый html и некоторые входные данные, подобные этому:
*.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": {
...
}
}
}
Затем в моем HTML-файле у меня есть что-то вроде:
<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>
И в моем контроллере Angular у меня есть вызов ajax для файла JSON:
контроллер:
.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)});
}
HTML заполнен, но я не могу использовать $watch для модели (q), созданной с помощью этого подхода.
Как я могу $ отслеживать изменения в моделях, созданных таким образом?
Заранее спасибо…
Комментарии:
1. Вы должны создать директиву, которая будет
$compile
содержать повторяющийся div. Создайте plunkr или fiddle, и я создам эту директиву, если вы не знаете, как это сделать.2. ОК. это пример того, как это должно работать: jsfiddle.net/carloscarcamo/Dh3Su И это код того, что я пытаюсь сделать: jsfiddle.net/carloscarcamo/gtV2F В последнем случае моя модель работает некорректно, поскольку я генерирую html-код с помощью ng-bind-html, а html-код загружается с сервера (в данном случае из файла json). @akn Я буду признателен за вашу помощь с директивой
3. между этими скриптами нет разницы
4. @akn Извините за это, это второе: jsfiddle.net/carloscarcamo/nZ89y/1
Ответ №1:
Вы должны скомпилировать динамически создаваемые элементы, чтобы сообщить angular о них.
Директива, которая может это сделать, может выглядеть следующим образом:
app.directive('compile',function($compile, $timeout){
return{
restrict:'A',
link: function(scope,elem,attrs){
$timeout(function(){
$compile(elem.contents())(scope);
});
}
};
});
$timeout
используется для запуска функции компиляции после ng-bind-html
выполнения ее работы.
Теперь вы можете просто поместить compile
в качестве атрибута div с 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>
Скрипка:http://jsfiddle.net/nZ89y/7
Комментарии:
1. ого-го!!! это выглядит так просто, это действительно работает, @akn большое вам спасибо, я обязательно буду использовать эту директиву в своих проектах 🙂
2. Я попробовал ссылку jsFiddle. Я вижу синтаксические ошибки в консоли javascript Chrome. Произошло ли что-нибудь за последние 8 месяцев, чтобы нарушить это?
3. @dfoverdx, кажется, это все время было неправильно. Возникли некоторые проблемы с вводом ng-модели. Должно быть
q['1']
вместоq.1
. Я также заменил"
на'
. Обновленная скрипка: 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>
Комментарии:
1. Хотя этот код может работать. но вам может потребоваться предоставить достаточное описание того, как это работает, чтобы разъяснить другим пользователям