动态输入编译

Dynamic input compilation

我尝试根据返回的对象服务器动态构建输入。 我使用 angularJS 指令。 由于对象是树状的,所以我使用了递归。

生成的问题不要绑定模型。

HTML:

<div ng-app="dyno">
  <div ng-controller="fieldCompilation">
    <br><br><b> Directive Inputs 1 (param via attr):</b><br>

    <form action="" name="myForm1" novalidate>
      <div ng-repeat="(itbl, tbl) in from1">
        <div ng-repeat="(irec, rec) in tbl">
          <div ng-repeat="(iel, el) in rec">
            <build-fields1 list="el"></build-fields1>
          </div>
        </div>
      </div>
      Form validity: {{myForm1.$valid}}<br>
            Model: {{from1[1][1061][0].value}}
    </form>
    <br>
  </div>
</div>

JS:

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

app.directive('buildFields1', ['$compile',
  function($compile) {
    return {
      restrict: 'E',
      scope: {
        list: '=list'
      },
      link: function(scope, element, attr) {
        var e = scope.list;
        switch (e.tagName) {
          case 'input':
            element.append(e.label + ' <' + e.tagName + ' name="' + e.name + '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="' + e.func + '(' + e.param + ')" ng-model="' + e.value + '" ' + e.attrs.toString() + '>');
            break;
                    case 'select':
          element.append(e.label + '<' + e.tagName + ' name="'+e.name+'" ng-change="'+e.func+'(-2)" ng-model="'+e.name+'" ng-options="x.id as x.name for x in '+e.items.toString()+'">');
                    break;
          case 'ref':
            element.append('<div ng-repeat="(itbl, tbl) in $parent.' + e.value + '"><div ng-repeat="(irec, rec) in tbl"><div ng-repeat="(iel, el) in rec"><build-fields1 list="el"></build-fields1></div></div></div>');
            break;
        }

        $compile(element.contents())(scope);
      }
    };
  }
]);
app.controller('fieldCompilation', function($scope) {
  var i;
  // FORM2
  // FORM1
  $scope.from1 = [{}];
  $scope.from1[1] = {};
  $scope.from1[1][1061] = {};
  i = 0;
  $scope.from1[1][1061][i++] = {
    tagName: 'input',
    name: 'tid',
    label: 'TID:',
    attrs: ["required pattern='[0-9]{8}'"],
    func: 'show',
    param: '20',
    value: '20000000',
  };
  $scope.from1[1][1061][i++] = {
    tagName: 'input',
    name: 'mid',
    label: 'MID:',
    attrs: ["required pattern='[0-9]{15}'"],
    func: 'show',
    param: '20',
    value: '123456789012345',
  };
  $scope.from1[1][1061][i++] = {
    tagName: 'select',
    name: 'sel',
    label: 'Class:',
    attrs: [],
    items: "[{id:'1',name:'A'},{id:'2',name:'B'},{id:'3',name:'C'}]",
    func: 'show',
  };
  $scope.from1[1][1061][i++] = {
    tagName: 'ref',
    name: 'ref',
    label: 'Ref:',
    attrs: ["required pattern='[0-9]{8}'"],
    func: 'show',
    param: '1', // of function
    value: 'from2',
  };

  $scope.from2 = [{}];
  $scope.from2[2] = {};
  $scope.from2[2][10] = {};
  i = 0;
  $scope.from2[2][10][i++] = {
    tagName: 'input',
    name: 'a',
    label: 'A:',
    attrs: ["required pattern='[0-9]{8}'"],
    func: 'show',
    param: '20',
    value: '10000001',
  };
  $scope.from2[2][10][i++] = {
    tagName: 'input',
    name: 'b',
    label: 'B:',
    attrs: ["required pattern='[0-9]{15}'"],
    func: 'show',
    param: '20',
    value: '882277441115599',
  };
  $scope.from2[2][10][i++] = {
    tagName: 'select',
    name: 'c',
    label: 'C:',
    attrs: [],
    items: "[{id:'1',name:'a'},{id:'2',name:'b'},{id:'3',name:'c'}]",
    func: 'show',
  };


});

预期结果是:当我在 (f.e.TID) 中输入内容时,它的模型应该相应地改变。 现在我得到一个固定值,其中根本无法更改。 Fiddle

换行

element.append(e.label + ' <' + e.tagName + ' name="' + e.name 
   + '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="'
   + e.func + '(' + e.param + ')" ng-model="' + e.value + '" '
   + e.attrs.toString() + '>');

element.append(e.label + ' <' + e.tagName + ' name="' + e.name
   + '" placeholder="' + e.attrs.toString() + '" type="text" ng-change="'
   + e.func + '(' + e.param + ')" ng-model="list.value" '
   + e.attrs.toString() + '>');

如果您调试代码并查看编译后的实际值:

<input name="tid" placeholder="required pattern='[0-9]{8}'" type="text"
       ng-change="show(20)" ng-model="20000000" required=""
       pattern="[0-9]{8}"
       class="ng-pristine ng-valid ng-scope ng-valid-required ng-valid-pattern ng-touched">

请注意 ng-model="2000000",这就是您永远无法更改它的原因。因为您正在编译它,所以您希望范围内的值 ng-model="list.value"$scope.list.value,因此可以被 ng-model 接受。