21

Làm thế nào ai đó có thể sử dụng formName.inputName. $ Valid khi "inputName" được tạo động?Thuộc tính tên biểu mẫu động <input type = "text" name = "{{variable-name}}" /> trong Angularjs

<form name="formName"> 
    <input ng-repeat="(variable) in variables" 
      type="text" name="variable.name" 
      ng-model="variable.name" required /> 
</form> 

Đầu ra của thuộc tính 'tên' HTML đầu vào sẽ là chuỗi "variablename", mà sẽ áp dụng cho tất cả các đầu vào lặp đi lặp lại.

Nếu chúng ta cố gắng này

<form name="formName"> 
    <input ng-repeat="(variable) in variables" 
     type="text" name="{{ variable.name }}" 
     ng-model="variable.name" required /> 
</form> 

Đầu ra của thuộc tính 'tên' HTML đầu vào sẽ là chuỗi "{{variable.name}}", trong đó sẽ được áp dụng cho TẤT CẢ đầu vào lặp đi lặp lại.

Trong một trong hai điều kiện này, thuộc tính tên cho từng yếu tố đầu vào được lặp lại sẽ không được tạo động; TẤT CẢ các đầu vào sẽ chia sẻ cùng một tên đầu vào. Không tốt lắm nếu bạn muốn gọi một đầu vào cụ thể dựa trên một tên cụ thể.

  • nhu cầu sử dụng tên động đánh giá cao
  • cần để có thể gọi $ scope.formName.dynamicName. $ Hợp lệ
  • cần để có thể gọi $ scope.formName. $ Hợp lệ
  • cần các trường nhập tên động sẽ được thêm vào biểu mẫu lồng nhau hoặc biểu mẫu chính
+0

http://stackoverflow.com/questions/21455695/angularjs-dynamic-form-field-validation/21457121#21457121 –

Trả lời

1

Tôi không thể tìm thấy câu trả lời thỏa mãn một số hoặc tất cả các nhu cầu này. Đây là những gì tôi nghĩ ra.

Có thể có cách nào tốt hơn, vì vậy hãy chia sẻ suy nghĩ của bạn.
Tôi đang sử dụng Angularjs 1.3.0-beta.8

Tôi có một mẫu với chỉ thị đa lồng nhau mà tất cả đều chứa đầu vào (s), chọn (s), vv ... Những yếu tố này đều kèm theo trong ng-lặp lại, và giá trị chuỗi động.

Đây là cách sử dụng chỉ thị:

<form name="myFormName"> 
    <nested directives of many levels> 
    ex: <input ng-repeat=(index, variable) in variables" type="text" 
       my-name="{{ variable.name + '/' + 'myFormName' }}" 
       ng-model="variable.name" required /> 
    ex: <select ng-model="variable.name" ng-options="label in label in {{ variable.options }}" 
       my-name="{{ variable.name + '/' + 'myFormName' }}" 
     </select> 
</form> 

Lưu ý: bạn có thể thêm và chỉ số để các nối chuỗi nếu bạn cần để serialize lẽ một bảng đầu vào; đó là những gì tôi đã làm. Tuy nhiên, đầu vào tên động có nghĩa là bạn có thể không biết tên của đầu vào biểu mẫu, vì vậy làm thế nào bạn sẽ gọi $ scope.formName. ??????. Bạn có thể lặp lại đối tượng $ scope.formName để nhận các khóa khớp với một giá trị nhất định. Điều đó có nghĩa nối chuỗi như thế này:

my-name="{{ dynamicString + hello + '/' + 'myFormName' }}" 

Sau đó trong $ scope.myFormName bạn sẽ tìm thấy bất kỳ tên đầu vào hình thức bằng cách chỉ cần lặp lại so với đối tượng và thu thập bất kỳ phím bao gồm 'hello'.

app.directive('myName', function(){ 

    var myNameError = "myName directive error: " 

    return { 
    restrict:'A', // Declares an Attributes Directive. 
    require: 'ngModel', // ngModelController. 

    link: function(scope, elem, attrs, ngModel){ 
     if(!ngModel){ return } // no ngModel exists for this element 

     // check myName input for proper formatting ex. something/something 
     checkInputFormat(attrs); 

     var inputName = attrs.myName.match('^\\w+').pop(); // match upto '/' 
     assignInputNameToInputModel(inputName, ngModel); 

     var formName = attrs.myName.match('\\w+$').pop(); // match after '/' 
     findForm(formName, ngModel, scope); 
    } // end link 
    } // end return 

    function checkInputFormat(attrs){ 
    if(!/\w\/\w/.test(attrs.rsName)){ 
     throw myNameError + "Formatting should be \"inputName/formName\" but is " + attrs.rsName 
    } 
    } 

    function assignInputNameToInputModel(inputName, ngModel){ 
    ngModel.$name = inputName 
    } 

    function addInputNameToForm(formName, ngModel, scope){ 
    scope[formName][ngModel.$name] = ngModel; return 
    } 

    function findForm(formName, ngModel, scope){ 
    if(!scope){ // ran out of scope before finding scope[formName] 
     throw myNameError + "<Form> element named " + formName + " could not be found." 
    } 

    if(formName in scope){ // found scope[formName] 
     addInputNameToForm(formName, ngModel, scope) 
     return 
    } 
    findForm(formName, ngModel, scope.$parent) // recursively search through $parent scopes 
    } 
}); 

Điều này sẽ xử lý nhiều tình huống mà bạn không biết biểu mẫu sẽ ở đâu. Hoặc có lẽ bạn có các biểu mẫu lồng nhau, nhưng vì một lý do nào đó bạn muốn đính kèm tên đầu vào này vào hai biểu mẫu? Vâng, chỉ cần vượt qua trong tên biểu mẫu bạn muốn đính kèm tên đầu vào.

Những gì tôi muốn, là một cách để gán giá trị động cho đầu vào mà tôi sẽ không bao giờ biết, và sau đó chỉ cần gọi $ scope.myFormName. $ Valid.

Đây có thể là quá mức cần thiết và giải pháp tốt hơn tồn tại trong 1,3+. Tôi không thể tìm thấy nó trong thời gian tôi có. Điều này làm việc cho tôi bây giờ.

Chúc may mắn! Hy vọng điều này sẽ giúp ai đó !!!!

+0

Chắc chắn đã giúp với tình huống lồng nhau của tôi.Tôi đã thực hiện một chỉnh sửa nhỏ: Trong hàm 'checkInputFormat' bạn nên kiểm tra' attrs.myName'. –

+0

Oh btw, giải pháp nào tốt hơn trong AngularJS 1.3+? –

+0

Tôi chưa tìm thấy nó. Tôi sẽ tiếp tục tìm kiếm. – SoEzPz

-1

Đừng quên rằng bạn có thể truy cập các đối tượng javascript sử dụng ký hiệu mảng với chỉ mục chuỗi. Căn cứ vào đối tượng sau đây tùy ý nghĩa hình thức:

$scope.form_def = { 
    form_name : 'BallForm', 
    variables : [ 
    height : { name : 'Height', type : 'text' }, 
    width : { name : 'Width', type : 'text' }, 
    color : { name : 'Color', type : 'multi', options : ['red', 'green', 'blue'] } 
    ] 
}; 
$scope.form_values = {}; 

... và đoạn mã html ...

<form name="{{ form_def.form_name }}"> 
    <div ng-repeat="variable in form_def.variables"> 
    <input ng-if="variable.type==='text'" type="text" name="{{ variable.name }}" ng-model="form_values[variable.name]"> 
    <select ng-if="variable.type==='multi'" name="{{ variable.name }}" ng-model="form_values[variable.name]"> 
     <option ng-repeat="opt in variable.options" value="{{ opt }}">{{ opt }}</option> 
    </select> 
    </div> 
</form> 

Bên trong bộ điều khiển sau đó bạn sẽ có một form_values ​​đẹp phản đối cho mọi lĩnh vực mà bạn có thể truy cập bằng cách lặp qua các khóa trong băm form_def.variables.

Có nhiều sự tham gia hơn nữa khi bạn viết ra các kiểu xử lý biểu mẫu chung này và bạn kết thúc với rất nhiều mã spaghetti theo ý kiến ​​của tôi và có lẽ bạn nên đi với ít hơn giải pháp chung, nhưng đó là một câu hỏi SO khác.

16

Hình như góc 1.3 cố định này (https://stackoverflow.com/a/32907176/3854385)

này bây giờ có thể với 1.3+ góc:

<form name="vm.myForm" novalidate> 
    <div ng-repeat="p in vm.persons"> 
    <input type="text" name="person_{{$index}}" ng-model="p" required> 
    <span ng-show="vm.myForm['person_' + $index].$invalid">Enter a name</span> 
    </div> 
</form> 

Demo

Trong một số trường hợp một hình thức bên trong là một giải pháp tốt nếu bạn chỉ có thể vượt qua thông tin: (https://stackoverflow.com/posts/12044600/) Để giải quyết vấn đề 'tên động' bạn nee d để tạo ra một hình thức bên trong (xem ng-form):

<div ng-repeat="social in formData.socials"> 
     <ng-form name="urlForm"> 
      <input type="url" name="socialUrl" ng-model="social.url"> 
      <span class="alert error" ng-show="urlForm.socialUrl.$error.url">URL error</span> 
      <button ng-click="doSomething(urlForm.socialUrl.$valid)">Test</button> 
     </ng-form> 
    </div> 

Các thay thế khác sẽ được để viết một chỉ thị tùy chỉnh cho việc này.

Dưới đây là jsFiddle cho thấy việc sử dụng các ngForm: http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/

+1

ng-show = "vm.myForm ['person _ {{$ index}}'] . $ invalid "nên là ng-show =" vm.myForm ['person_' + $ index]. $ invalid "nó mong đợi một biểu thức đánh giá thành một chuỗi không phải là một chuỗi –

+0

Điều đó có nghĩa là cả hai sẽ tương đương sau đó, đúng ? Hay bạn đã nhận được một số lỗi với tùy chọn đầu tiên? (Tôi đã sử dụng một Angular 1.x vì vậy nó sẽ làm việc ở đó cho chắc chắn. Nếu bạn đang ở trên 2.x, họ có thể đã thay đổi cách nó đánh giá mọi thứ.) – Loren

+0

Góc 1.x đây là một plunkr từ các tài liệu góc được sửa đổi để sử dụng phương pháp tôi đề nghị https://plnkr.co/edit/meW6azMBI60ZiRA1GQcU?p=preview đây là một plunkr sử dụng phương pháp nội suy https://plnkr.co/edit/ibzhEhCNPLqZCflXHLW3?p=preview như bạn có thể thấy nó dẫn đến ngMessages giá trị không được phân tích cú pháp chính xác –

0

làm việc cho tôi với góc 1.2.7

chỉ:

var DynamicName = function() { 
    return { 
     restrict: 'A', 
     priority: -1, 
     require: ['ngModel'], 
     link: function (scope, element, attr, ngModel) { 
      ngModel[0].$name = attr.name; 
     } 
    }; 
}; 

app.directive('dynamicName', DynamicName); 

howtouse:

<div ng-repeat="phone in hrModel.phones"> 
    <input type="text" 
      name="phones[{{$index}}]" 
      ng-model="phones[$index]" 
      dynamic-name 
    /> 
</div> 
0

Biên dịch Tên Input

  1. Khi ai đó chỉ ra, các phiên bản hiện đại của góc đã cố định này ...
  2. này phải thiết lập các thuộc tính tên trên đầu vào của bạn, và thêm bộ điều khiển mô hình mẫu:
 
    angular.module('MOD') 
     .directive('compiledName', compiledNameDirective); 

    function compiledNameDirective() { 
     return { 
      restrict: 'A', 
      require: ['ngModel', '?^form'], 
      scope: { 
       name: '@compiledName' 
      }, 
      link: function checkboxIndeterminateLink(scope, element, attributes, required) { 
       var ngModelController = required[0], ngFormController = required[1]; 
       ngModelController.$name = scope.name; 
       element.attr('name', scope.name); 
       if (ngFormController) ngFormController.$addControl(ngModelController); 
      } 
     }; 
    } 


    

Các vấn đề liên quan