3

我正在生成一份包含问题集合的报告。

app.controller('reportCtrl', ['$scope','$stateParams', function ($scope, $stateParams) {

    $scope.questions: [
        { questionkey: 1, questiontext: 'Type', questiontype: 1 , questionmodel:'accsType' },
        { questionkey: 2, questiontext: 'Reported By', questiontype: 1, questionmodel: 'accsReportedBy' },
        { questionkey: 3, questiontext: 'Time and Date', questiontype: 6, questionmodel: 'accsCurrentDate' },
        { questionkey: 4, questiontext: 'Address', questiontype: 2, questionmodel: 'accsAddress' },
        { questionkey: 5, questiontext: 'Coordinates', questiontype: 6, questionmodel: 'accsCoordinates' },
        { questionkey: 6, questiontext: 'Blank', questiontype: 1, questionmodel: 'accsBlank1' },
        { questionkey: 7, questiontext: 'Blank', questiontype: 1, questionmodel: 'accsBlank2' },
        { questionkey: 8, questiontext: 'Blank', questiontype: 1, questionmodel: 'accsBlank3' },
        { questionkey: 9, questiontext: 'Blank', questiontype: 1, questionmodel: 'accsBlank4' },
        { questionkey: 10, questiontext: 'Details of Survey', questiontype: 2, questionmodel: 'accsDetailsSurvey' },
        { questionkey: 11, questiontext: 'Photos', questiontype: 5, questionmodel: 'accsPhotos' }
    ];

}]);

我创建了一个自定义指令来根据问题类型绘制问题例如问题类型 1 是文本框类型 2 是 textarea

<question contents="questions"></question>

app.directive('question', function ($compile) {
    return {
        transclude: true,
        restrict: 'E',
        scope: {
            contents: '='
        },  
        link: function (scope, element, attrs) {   
            angular.forEach(scope.contents, function (k, v) {
                var ele;

                switch (parseInt(k.question.questiontype)) {
                    case 1:
                        ele = $compile("<accstextbox data='k.question'></accstextbox>")(scope);
                        break;
                    case 2:
                        ele = $compile("<accstextarea data='k.question'></accstextarea>")(scope);
                        break;
                }

                element.append(ele);
            });
        }         
    };
});

我为每种问题类型创建了一个指令

app.directive('accstextbox', [function () {
    return {
        restrict: 'E',
        templateUrl: 'app/directives/questions/textbox.html',
        link: function (scope, element, attrs) {
           console.log(scope.data); // undefined
        },
        scope:{
            data: '='
        }
    };
}]);

app.directive('accstextarea', [function () {
    return {
        restrict: 'E',
        templateUrl: 'app/directives/questions/textarea.html',
         link: function (scope, element, attrs) {
           console.log(scope.data); // undefined
        },
        scope: {
            data: '='
        }
    };
}]);

当我动态添加这些指令时,我通过属性传递数据对象。该数据对象在子指令范围内未定义。我第一次在我的项目中使用 angularjs。

4

2 回答 2

1

正如 Vinicius 指出的那样,您在文本字符串中k的循环内使用对象,forEach因此 angular 无法解决您的意思k.questions

question我提出了一个类似的解决方案来重复你的指令中的 ng-repeat 中的问题:

<div>
  <div ng-repeat="q in contents">
    <div ng-switch="q.questiontype">
      <div ng-switch-when="1">
        <accstextbox> one: {{q.questiontext}}</accstextbox>
      </div>
      <div ng-switch-when="2">
        <accstextarea> two : {{q.questiontext}}</accstextarea>
      </div>
    </div>
  </div>
</div>

另一种选择是将选择模板类型的逻辑移动到子指令中。如果你唯一的改变是输入的类型,我更喜欢这个选项,并且逻辑上没有太大的区别,所以你会避免重复你的代码,即子指令模板将包含输入选择逻辑:

<div>
  <div ng-if="question.questiontype === 1">
    <input type="text"/>
  </div>
  <div ng-if="question.questiontype === 2">
    <textarea name="" id="" cols="30" rows="10"></textarea>
  </div>
</div>
于 2016-01-01T19:54:56.653 回答
1

您的解决方案将不起作用,因为k它是一个局部变量并且$compiler服务无法访问。

一个解决方案是使用您的指令ngRepeatngIf通过模板生成最终布局:

app.directive('question', function ($compile) {
    return {
        transclude: true,
        restrict: 'E',
        templateUrl: 'app/directives/questions.html',
        scope: {
            contents: '='
        }      
    };
});

app/directives/questions.html

<div ng-repeat="question in contents">
    <accstextbox ng-if="question.questiontype == 1" data="question"></accstextbox>
    <accstextarea ng-if="question.questiontype == 2" data="question"></accstextarea>
</div>

由于这是一个非常小的模板,您可以将其添加到template指令的配置参数中,而不是通过templateUrl.

希望对你有帮助!

于 2016-01-01T19:27:55.147 回答