在AngularJS中动态生成ng-model

时间:2014-12-17 17:19:22

标签: javascript html angularjs

我正在尝试使用过滤器动态生成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在最简单的事情上有多么困难感到有些沮丧,所以任何帮助都会非常感激。

由于

2 个答案:

答案 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还没有准备好。不知道这是不是一个好的做法,但它是我能找到的唯一方法。

非常感谢任何建议或建议。