1

我已經爲表單字段創建了一個動態的templateUrl,我試圖在ng-repeat中附加ng模型。父指令和表單字段指令都可以工作並生成,但是當我使用ng模型時,它似乎不工作,預輸出不會改變?在這個用例中應用ng-model有一個竅門嗎?它工作,如果我只是使用硬編碼的形式輸入。我一直在關注AngularJS文檔中的example。圍繞表單字段AngularJS ng模型不工作在動態創建的輸入字段

周邊標記:

<form role="form" ng-controller="FormController as formCtrl" novalidate> 

    <div ng-repeat="field in panel.form_fields"> 

     <form-field field="field"></form-field> 

    </div> 

    <fieldset class="form-group clearfix"> 
     <button type="submit" class="btn btn-primary pull-right">Save Progress</button> 
    </fieldset> 

    <pre>form = {{models | json}}</pre> 
    <pre>master = {{master | json}}</pre> 
</form> 

表單字段的指令:使用

angular.module('formField.directives', []) 

.directive('formField', [ '$http', '$compile', function($http, $compile) { 

    var getTemplateUrl = function(field) { 

     var type = field.field_type; 
     var templateUrl = ''; 

     switch(type) { 
      case 'textfield': 
       templateUrl = 'components/form-field/fields/textfield.html'; 
       break; 
      case 'email': 
       templateUrl = 'components/form-field/fields/email.html'; 
       break; 
      case 'currency': 
       templateUrl = 'components/form-field/fields/currency.html'; 
       break; 
      case 'date': 
       templateUrl = 'components/form-field/fields/date.html'; 
       break; 
      case 'dropdown': 
       templateUrl = 'components/form-field/fields/dropdown.html'; 
       break; 
      case 'textarea': 
       templateUrl = 'components/form-field/fields/textarea.html'; 
       break; 
      case 'hidden': 
       templateUrl = 'components/form-field/fields/hidden.html'; 
       break; 
      case 'password': 
       templateUrl = 'components/form-field/fields/password.html'; 
       break; 
      case 'checkbox': 
       templateUrl = 'components/form-field/fields/checkbox.html'; 
       break; 
      case 'radio': 
       templateUrl = 'components/form-field/fields/radio.html'; 
       break; 
     } 

     return templateUrl; 
    } 

    var linker = function(scope, element) { 

     var templateUrl = getTemplateUrl(scope.field); 
     $http.get(templateUrl).success(function(data) { 
      element.html(data); 
      $compile(element.contents())(scope); 
     }); 
    } 

    return { 
     restrict: 'E', 
     replace: true, 
     scope: { 
      field: '=' 
     }, 
     link: linker 
    } 
}]); 

表單字段模板:

<fieldset class="form-group"> 

    <label for="{{field.field_name}}">{{field.field_label}}</label> 
    <input type="text" 
      class="form-control" 
      id="{{field.field_id}}" 
      name="{{field.field_name}}" 
      value="{{field.field_value}}" 
      placeholder="{{field.field_prompt}}" 
      ng-required="field.field_required" 
      ng-disabled="field.field_disabled" 
      ng-model="models[field.field_name]"> // model.test also doesn't work, and need to be able to reference the model dynamically 

</fieldset> 

控制器從實施例中使用在AngularJS文檔:

.controller('FormController', ['$scope', function($scope) { 

    $scope.master = {}; 
    $scope.models = {}; 

    $scope.update = function(models) { 
     console.info('Update'); 
     $scope.master = angular.copy(models); 
    }; 

    $scope.submit = function() { 
     console.info('Form Submitted'); 
    }; 

    $scope.cancel = function() { 
     console.info('Form Cancelled'); 
    }; 

    $scope.clear = function() { 
     console.info('Form Clear'); 
     $scope.models = {};    
    } 

    $scope.reset = function() { 
     console.info('Form Reset'); 
     $scope.models = angular.copy($scope.master); 
    }; 

    $scope.reset(); 

}]); 
+0

你可以準備演示嗎?你的指令如何看起來像 – PSL 2014-09-03 01:10:16

+0

你可以添加「表單字段」指令的聲明嗎? – Josep 2014-09-03 01:12:21

+3

您正在使用獨立作用域,它不知道上下文之外的「模型」是什麼。現在看它http://plnkr.co/edit/HOxGGw?p=preview – PSL 2014-09-03 01:21:01

回答

3

您的指令適用於隔離範圍(.$new(true)),這意味着您在指令中所做的更改不會直接在外部範圍中提供(除非您使用雙向綁定等)。所以ng-model="models[field.field_name]"models裏面你的指令不是models對象在你的作用域上的父控制器中。所以你可以通過使用雙向綁定來傳遞模型來修復它。

雖然耗時: -

<form-field field="field" model="models[field.field_name]"></form-field> 

在你的指令模板: -

<input type="text" 
     class="form-control" 
     id="{{field.field_id}}" 
     name="{{field.field_name}}" 
     value="{{field.field_value}}" 
     placeholder="{{field.field_prompt}}" 
     ng-required="field.field_required" 
     ng-disabled="field.field_disabled" 
     ng-model="model"> <!-- Here just set the model on the scope 2-way B --> 

,並在你的指令隔離聲明範圍做: -

scope:{field:'=', model:'='}, 
    //or set a reference to the object on scope holding models in the field property itself. 

Plnkr

請注意,在指定模板中,當您指定value="{{field.field_value}}"ng-model時,它根本不會設置默認值。你需要在ngModel中默認它。

+3

很好的答案! @mtpultz你可能想看看這個:https://docs.angularjs.org/guide/scope。此外,您用於'fieldset'標籤的語義有點不協調。 'fieldset'標籤應該用於分組字段,所以不要爲每個字段創建'fieldset'標籤,也許你應該使用它來保存它們。 – Josep 2014-09-03 03:28:10

+0

@Josep這是一個很好的觀點。我沒有注意到模板中有一個fieldset .. :) – PSL 2014-09-03 03:30:40

+0

感謝@PSL,這是一個很好的解釋,同時也感謝您指出了有關默認值的問題。乾杯:) – mtpultz 2014-09-03 06:11:48