如何在angularjs 1.6中将动态元素绑定到DOM?

时间:2018-05-30 11:56:07

标签: angularjs

我正在创建一个可以有多行的动态报表生成器。这些行是根据所选字段动态创建的。我通过我的js控制器附加动态HTML,但ng-model没有绑定到DOM。我尝试添加$ compile(element)($ scope)但它没有用。请查看下面分享的屏幕截图。

HTML

<div class="page-content-wrap">
  <form name="reportform" class="reportBuilder" ng-submit="getReport(reportform,report)">
    <div class="row">
      <div class="form-group col-md-4">
        <select class="form-control" name="module" id="module"
                ng-model="modules"
                ng-options="module as module.formname for module in allModules track by module.id"
                ng-change="getFields()">
            <option value="" class="">Select Module</option>
        </select>
      </div>
    </div>
    <div class="dynamic_block">
      <div class="row">
        <div class="form-group">
          <div class="col-md-4">
            <select class="form-control field_type"
                    ng-model="fields[row_count]"
                    ng-options="moduleField.name as (moduleField.label) for moduleField in moduleFields">
                <option value="" class="">Select Fields</option>
            </select>
          </div>
          {{options}}
          <div class="col-md-7 field_to_be_added">
            &nbsp;
          </div>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-12">
        <span ng-click="cloneRow()"><i class="fa fa-plus-circle"></i></span>
      </div>
    </div>
    <div class="row">
      <div class="col-md-6">
        <button class="btn btn-primary" type="submit">Generate Report</button>
      </div>
    </div>
  </form>
</div>

的JavaScript

$scope.cloneRow = function() {
        $scope.row_count++;
        $scope.model_name = 'field_'+$scope.row_count;
        var new_html = $('#dynamic_block_fixed').clone();
        $('.dynamic_block:last').after(new_html);
        $compile(new_html)($scope);
        $('.minus-icon').unbind().bind('click',function(item){
            $(item.target).closest('div.dynamic_block').remove();
        });
        $('.field_type').unbind().bind('change',function(item){
            var item_id = $(this).val().split(':');
            for(fields in $scope.moduleFields){
                if(typeof $scope.moduleFields[fields] != 'undefined') {
                    if($scope.moduleFields[fields]['name'] == item_id[1]){
                        createFieldOptions($scope.moduleFields[fields],item.target.parentElement);
                    }
                }
            }
        });
    }


function createFieldOptions(field, target) {
  for (f in field) {
    var name = field['name'];
    if (field[f] == 'text') {
      var element = `<input class="form-control" dynamic type="text" ng-model="report.${name}"/>`;
    } else if (field[f] == 'textarea') {
      var element = `<textarea class="form-control" ng-model="report.${name}"></textarea>`;
    } else if (field[f] == 'select') {
      var options = [];
      for (key in $scope.moduleFields) {
        var objectValues = $scope.moduleFields[key];
        if (objectValues['type'] == 'select' && objectValues['name'] == name) {
          options = objectValues['values'];
        }
      }
      var element = `<select class="form-control" ng-model="report.${name}"><option>Select</option>`;
      options.forEach(function(object) {
        element += `<option value="${object.value}">${object.label}</option>`;
      });
      element += "</select>";
    } else if (field[f] == 'checkbox-group') {
      var checkoptions = [];
      for (key in $scope.moduleFields) {
        var objectValues = $scope.moduleFields[key];
        if (objectValues['type'] == 'checkbox-group' && objectValues['name'] == name) {
          checkoptions = objectValues['values'];
        }
      }
      var element = "<span>";
      checkoptions.forEach(function(object) {
        element += `<label class="check"><input type="checkbox" name="${name}" ng-model="report.${name}" value="${object.value}"/>${object.label}</label>`;
      });
      element += "</span>";
    } else if (field[f] == 'date') {
      element = `<input type="date" name="${name}" ng-model="report.${name}"/>`;
    } else if (field[f] == 'radio-group') {
      var radiooptions = [];
      for (key in $scope.moduleFields) {
        var objectValues = $scope.moduleFields[key];
        if (objectValues['type'] == 'radio-group' && objectValues['name'] == name) {
          radiooptions = objectValues['values'];
        }
      }
      var element = "<span>";
      radiooptions.forEach(function(object) {
        element += `<label class="check"><input type="radio" name="${name}" ng-model="report.${name}" value="${object.value}"/>${object.label}</label>`;
      });
      element += "</span>";
    }
  }
  angular.element(target).next('div.col-md-7').html(element);
  //$(target).next('div.col-md-7').html(element);
  $compile(element)($scope);
  $scope.$apply();
}

如果有的话,可以选择其他方法。

Screenshot

1 个答案:

答案 0 :(得分:-1)

听起来你正在用JQuery风格附加动态HTML,而parent.append(newHTML)有点像;这在AngularJS中并不是很好的做法,而且当你必须使用$compile时,你知道某些事情并不完全正确。

我建议在指令中构建代码,并通过ng-if显示和隐藏每个指令。

如果您提供一些HTML示例,我可以更深入地了解