我正在尝试使用过滤器动态生成ng-model指令。 主要思想是数据库中有一些文本。该文本具有由方括号([1],[2]等)之间的数字定义的间隙。目的是解析这些差距并将其转化为输入。然后应使用ng-model指令将这些输入绑定到变量,但我无法使其工作。
这是我的控制器:
app.controller('exerciseTemplateCtrl', ['$http', '$scope', '$sce', '$filter', '$compile', function($http, $scope, $sce, $filter, $compile){
// used to test the binding through ng-model
$scope.answers = [];
$http.get('encode_exercises.json')
.then(function(response){
$scope.firstExercise = response.data;
});
$scope.parseHtml = function(input){
input = $filter('gapToInput')(input);
return $sce.trustAsHtml(input);
};
}]);
这里我的过滤器'gapToInput'
app.filter('gapToInput', function(){
return function(input){
return input.replace(/\[[0-9]\]/g, '<input type="text" ng-model="answers">');
};
});
正如您所看到的,我使用“answers”变量绑定模型。 这是我的指令:
app.directive('exerciseTemplate', function(){
return{
restrict: 'E',
templateUrl: 'exercise-template.html'
};
});
index.html 包含上一个指令:
<exercise-template></exercise-template>
这里是我之前指令的模板(简化)
<div ng-controller="exerciseTemplateCtrl as e">
<div ng-repeat="exercise in firstExercise">
<div ng-repeat="(questionId, question) in exercise.q">
<div ng-bind-html="parseHtml(question.d.q)"></div>
</div>
</div>
<p><button>Check</button></p>
</div>
question.dq包含数据库中带有间隙的文本([1],[2]等),它正在成功应用过滤器(道歉,我没有足够的声誉来发布图像):
http://i.stack.imgur.com/W0NoI.png
问题在于,即使替换有效,ng-model指令也不会将每个输入与“answers”变量绑定。 对于我一直在阅读的内容,这是因为我必须再次重新编译模板,以便Angular再次解析所有ng-directive。试着做下面没有任何运气:
var scope = $scope;
$scope.parseHtml = function(input){
input = $filter('gapToInput')(input);
input = $compile(input)(scope);
return $sce.trustAsHtml(input);
};
我也跟着this thread并尝试将指令格式更改为以下内容:
app.directive('exerciseTemplate', ['$compile', '$http', function($compile, $http){
return {
restrict: 'E',
link: function(scope, element, attrs){
$http.get('exercise-template.html').then(function(result){
element.replaceWith($compile(result.data)(scope));
});
}
}
}]);
但它仍然没有约束模型。我开始对Angular在最简单的事情上有多么困难感到有些沮丧,所以任何帮助都会非常感激。
由于
答案 0 :(得分:1)
我还没有对这段代码进行测试,但这里的重点是你可以分开&#34;差距&#34;在ng-repeat上使用内联过滤器。这将返回一系列项目,您可以将模型建立在该项目的基础上。
<div ng-repeat="exercise in firstExercise">
<div ng-repeat="(questionId, question) in exercise.q | gapToInput">
<input ng-repeat="" type="text" ng-model="exercise.q[questionId].answer">
</div>
</div>
你的过滤器就像:
app.filter('gapToInput', function(){
return function(input){
return input.split(/\[[0-9]\]/g);
};
});
答案 1 :(得分:0)
经过一番调查后,我设法找到了解决我最初问题的方法。即使SoluableNonagon回答了问题,我也会发布另一种解决问题的方法。
这个想法非常类似于我第二次尝试重新编译模板,但我可能遗漏了一些东西,所以这里是完整的工作代码:
<强>指令强>:
app.directive('exerciseTemplate', function(){
return{
restrict: 'E',
scope: true,
templateUrl: '/exercise-template.html'
};
});
app.directive('qText', ['$compile', '$timeout', function($compile, $timeout){
return {
restrict: 'E',
link: function(scope, element, attrs){
$timeout(function(){
var output = element.html().replace(/\[[0-9]\]/g, '<input type="text" ng-model="answers">');
element.html(output);
$compile(element.contents())(scope);
});
}
}
}]);
<强>运动template.html 强>:
<q-text ng-bind-html="parseHtml(question.d.q)"></q-text>
这将获得&lt; q-text&gt;&lt; / q-text&gt;的内部HTML并将其传递给指令的link函数。然后我使用jQLite的html()函数来检索HTML并用输入替换每个间隙,之后我只需要在元素中放回HTML并重新编译模板。之后,每一个输入都会被&#34;答案&#34;绑定。通过ng-model指令变量。
我不得不使用$ timeout,否则,html()方法返回null,可能是因为DOM还没有准备好。不知道这是不是一个好的做法,但它是我能找到的唯一方法。
非常感谢任何建议或建议。