javascript - 具有不同字段类型的angularjs动态表单

标签 javascript angularjs typescript angular-directive

在我当前的项目中,我需要使用 AngularJS 创建一个动态表单。 我已经按照此视频中的想法构建了表格 here.

我似乎无法将提交的数据返回到我的 Controller 。我只在控制台日志中收到 undefined。

目前,表单的数据在加载状态之前在 ui-router 中解析,然后复制到 Controller 的数据属性。

与视频不同,我们的表格要求将问题分成几个部分。

数据中的每个部分都有一个 ng-repeat,然后嵌套的 ng-repeat 遍历每个问题。确定类型并通过 ng-switch 加载问题/字段类型的正确指令。

我还制作了一个小 Plunker 来帮助说明。 https://plnkr.co/edit/6dCnHiFDEYu03kfX07mr

最后有一些我不确定如何处理的类型,例如地址或电话号码将被视为一个问题类型但有多个字段。

(例如[街道] [城市] [州] [邮政编码])

Controller

namespace portal.dashboard.form{
class formCtrl{
    formData: portal.domain.interfaces.IHousingRequest;

    static $inject = ["formResolve"];
    constructor(private formResolve:any) {

        this.formData= this.loadHousingRequestFormData;
    }

    public submit(isValid,data) {
        if (isValid) {
            console.log(data);
        }
    }
}
angular
    .module("portal")
    .controller("formCtrl", formCtrl);
}

输入类型文本指令

namespace portal.directives {
function inputText(): ng.IDirective {
    return {
        scope: {
            model: '='
        },
        controller: function ($scope: ng.IScope) {
            var directiveScope = $scope.$parent.$parent;
        },
        controllerAs:'vm',
        templateUrl: 'form/templates/input-text.html'            
    }
}

angular
    .module("portal")
    .directive("inputText", inputText);
}

输入类型html

<input type="text"
       ng-model="model"/>

HTML

    <form name="form" ng-submit="vm.submit(form.$valid, data)" novalidate>

    <!-- Section repeat -->
    <div ng-repeat="section in vm.formData.sections track by $index">
        <section>
            <div>
                <h4>
                    {{section.name}}<br />
                    <small ng-show="section.description">{{section.description}}</small>
                </h4>
            </div>
            <section>

                <!-- Section questions repeat -->
                <div ng-form="formFields" ng-repeat="field in section.fields track by $index">
                    <label>
                        {{field.name}}<br />
                        <small>{{field.description}}</small>
                    </label>

                    <!-- input field switch -->
                    <div ng-switch="field.type">
                        <div ng-switch-when="Text">
                            <input-text model="data.answer[$index]">
                            </input-text>
                        </div>
                        <div ng-switch-when="Email">
                            <input-email model="data.answer[$index]">
                            </input-email>
                        </div>
                    </div>
                </div>

            </section>
        </section>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</form>

最佳答案

你必须在使用它之前初始化 $scope.data = {};,还要使用正确的 sectionIndexfieldIndex 来填充答案:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.data = {};
  $scope.sections = [{
    name: 'User Info',
    description: 'I\'m a description.',
    fields: [{
      label: "Name",
      type: "text"
    }, {
      label: "Email",
      type: "email"
    }]
  }, {
    name: 'Pet Info',
    description: '',
    fields: [{
      label: "Pet Breed",
      type: "text"
    }]
  }];

  $scope.submit = function(isValid, data) {
    console.log('submit fired');
    if (isValid) {
      console.log(data);
    }
  }
});


app.directive('inputText', function() {
  return {
    scope: {
      model: '='
    },
    controller: function($scope) {
      var directiveScope = $scope.$parent.$parent;
    },
    controllerAs: 'vm',
    template: '<input type="text" ng-model="model"/>'
  }

});

app.directive('inputEmail', function() {
  return {
    scope: {
      model: '='
    },
    controller: function($scope) {
      var directiveScope = $scope.$parent.$parent;
    },
    controllerAs: 'vm',
    template: '<input type="email" ng-model="model"/>'
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>

<body ng-app="plunker" ng-controller="MainCtrl">
    <form name="form" ng-submit="submit(form.$valid, data)" novalidate>

    <!-- Section repeat -->
    <div ng-repeat="(sectionIndex, section) in sections track by $index">
        <section>
            <div>
                <h4>
                    {{section.name}}<br />
                    <small ng-show="section.description">{{section.description}}</small>
                </h4>
            </div>
            <section>

                <!-- Section questions repeat -->
                <div ng-form="formFields" ng-repeat="(fieldIndex, field) in section.fields track by $index">
                    <label>
                        {{field.label}}<br />
                    </label>

                    <!-- input field switch -->
                    <div ng-switch="field.type">
                        <div ng-switch-when="text">
                            <input-text model="data.answer[sectionIndex][fieldIndex]">
                            </input-text>
                        </div>
                        <div ng-switch-when="email">
                            <input-email model="data.answer[sectionIndex][fieldIndex]">
                            </input-email>
                        </div>
                    </div>
                </div>

            </section>
        </section>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</form>
  </body>

另外我不确定你为什么需要这个 var directiveScope = $scope.$parent.$parent;在你指令的 Controller 中,你真的需要这个吗?

关于javascript - 具有不同字段类型的angularjs动态表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45618298/

相关文章:

TypeScript 2.1 接口(interface)与 import from 合并

javascript - 事情是如何传递给 onClick 函数的

javascript - 如何在没有 Browserify 的情况下使用 CommonJS 依赖项?

php - jquery post() 不以动态形式工作

javascript - AngularJS ng-repeat 未检测到使用 ng-include 动态生成的数组

angularjs - 在禁用网络安全模式下运行的 Chrome 中,对预检请求的响应未通过访问控制检查

typescript - 对于任何 typescript 文件,WebStorm 变得非常慢

javascript - 如何顺序处理来自 API 的异步结果?

javascript - 无法读取未定义的属性 'open'。谷歌地图信息窗口循环

javascript - ng-click 和 ng-touch 移动设备