在 AngularJS 中动态生成 ng-model

Dynamically generate ng-model in AngularJS

本文关键字:ng-model 动态 AngularJS      更新时间:2023-09-26

我正在尝试使用过滤器动态生成 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="answerswers">');
    };
});

如您所见,我正在使用"答案"变量绑定模型。这是我的指示

app.directive('exerciseTemplate', function(){
  return{
    restrict: 'E',
    templateUrl: 'exercise-template.html'
  };
});

索引.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.d.q 包含数据库中带有间隙的文本([1]、[2] 等(,并且它成功应用了过滤器(抱歉,我没有足够的声誉来发布图像(:

https://i.stack.imgur.com/W0NoI.png

问题是,即使替换有效,ng-model 指令也不会将每个输入与"answerswers"变量绑定。对于我一直在阅读的内容,这是因为我必须再次重新编译模板,以便 Angular 再次解析所有 ng 指令。尝试执行以下操作,但没有任何运气:

var scope = $scope;
$scope.parseHtml = function(input){
    input = $filter('gapToInput')(input);
    input = $compile(input)(scope);
    return $sce.trustAsHtml(input);
};

我也遵循了这个线程并尝试将指令格式更改为以下内容:

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 的难度感到有点沮丧,即使是最简单的事情,所以任何帮助将不胜感激。

谢谢

我还没有测试过这段代码,但这里的重点是你可以使用内联的过滤器来分割"间隙"。这将返回一个项目数组,您可以基于此模型。

<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);
    };
});

经过一些调查,我设法找到了解决最初问题的方法。即使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="answerswers">');
                element.html(output);
                $compile(element.contents())(scope);
            });
        }
    }
}]);

练习模板.html

<q-text ng-bind-html="parseHtml(question.d.q)"></q-text>

这将获取 将其传递给指令的链接函数。然后我使用 jQLite 的 html(( 函数来检索 HTML 并用输入替换每个间隙,之后我只需要将 HTML 放回元素中并重新编译模板即可。之后,每个输入都将通过ng-model指令与"answerswers"变量绑定。

我不得不使用 $timeout,因为否则 html(( 方法返回 null,可能是因为 DOM 尚未准备就绪。不知道这是否是一个好的做法,但这是我能找到的唯一方法让它发挥作用。

任何建议或建议将不胜感激。