私は AngularJS アプリを作成しています。このアプリにはドメイン管理ツールがあります。ドメインが選択されると、テーブルにドメイン レコードを生成し、ユーザーが各行を編集できるようにします。フィールドは動的に作成されるため、同じ名前を共有しているため、ng-form を使用して各行を個別に検証できるようにします。
各ドメイン レコードには、IP、CNAME などが存在するコンテンツ フィールドがあります。選択されたレコード タイプ (A、CNAME、TXT など) に基づいて関数から生成された正規表現パターンを使用して、このフィールドを検証します。
問題は、たとえば A レコードを編集して、レコード タイプを CNAME に変更すると、コンテンツ フィールドの新しい検証が実行されていないため、フォームがまだ有効に見えることです。再検証する唯一の方法は、コンテンツ フィールドに入力を開始することです。
以下の画像を確認してください。
A レコードで編集を押すと、すべて問題なく表示されます。
レコード タイプを CNAME に変更すると、正規表現が変更されてもフォームは有効に見えます。タイプを変更すると、新しい正規表現が配置されているため、コンテンツ (1.2.3.4) を再検証する必要があります。
コンテンツ フィールドに入力を開始すると、フォームが正しく無効になります。入力を再開したときだけでなく、レコードタイプを変更したときにこれが発生することを望みます。
#Slim version of the template to give you an idea on whats going on
<form novalidate name="recordForm" class="css-form" ng-controller="EditRecordCtrl">
<table>
<tr ng-repeat="record in domain.data.0" class="gradeA">
<td ng-init="startingTypeData = record.type" class="domains-td" ng-switch on="record.edit">
<span ng-switch-default>{{record.type}}</span>
<span ng-switch-when="true">
<select ng-change="domainRecordContentType(record.type)" ng-init="domainRecordContentType(record.type)" ng-model="record.type" ng-options="c for c in domainRecordTypes" class="span12">
</select>
</span>
</td>
<td ng-init="startingContentData = record.content" class="domains-td validation-dropdown-error-parent" ng-switch on="record.edit">
<span ng-switch-default>{{record.content}}</span>
<span ng-switch-when="true">
<ng-form name="innercContentForm">
<span class="validation-dropdown-error" ng-show="innercContentForm.content.$error.pattern">
{{ 'RECORD_EDIT_FORM_RECORD_CONTENT_PATTERN_MSG' | translate }} ( {{ record.type }} )
</span>
<input type="text" ng-model="record.content" name="content" required class="span12 edit-record-input" ng-pattern="domainRecordContentRegex.0" required />
</ng-form>
</span>
</td>
</tr>
</table>
</form>
ドロップダウン メニューを変更したときに入力フィールドを再検証するにはどうすればよいですか?
プランカーの例: http://plnkr.co/edit/VAR5ho 注意! 最初の行に A レコードが表示されない小さなバグ。上の画像で行ったように、問題をテストすることもできます。
Thomas カスタム ディレクティブを使用して更新する
ドロップダウンを変更する前に
最初のドロップダウンを A から CNAME に変更すると、すべてのコンテンツ フィールドが消去されます
更新保存ボタン
<button ng-disabled="recordForm.$invalid" ng-switch-when="true" ng-if="hideRecordType(record.type)" ng-click="recordForm.$valid && editRecord(record, domainId); record.edit=false; $parent.startingNameData=record.name; $parent.startingTypeData=record.type; $parent.startingContentData=record.content; $parent.startingTTLData=record.ttl; $parent.startingPrioData=record.prio" type="submit" class="btn btn-block btn-primary btn-icon" ><i></i>{{ 'DOMAINS_SAVE_BUTTON' | translate }}</button>
最終更新..コンパイルされた要素に関する奇妙な動作
編集を押すと、通常の編集ビューに移動します
有効になるまで、新しい IP アドレスを入力し始めます
ドットを追加するなど、一度有効にした後にコンテンツを無効にすると、値が消去されます。なんで?
Thomas コードに基づく現在のディレクティブ:
domainModule.directive('revalidate', function($compile) {
return {
restrict: 'A',
link : function (scope, element, attrs) {
scope.$watch(attrs.ngModel, function (v) {
var reg = scope.$parent.domainRecordContentRegex[0];
if(!$(element).parent().parent().next().find('ng-form').find('input').val().match(reg)){
$compile($(element).parent().parent().next().find('ng-form').children('input[name="content"]').removeClass('ng-valid-pattern'))(scope);
$compile($(element).parent().parent().next().find('ng-form').children('input[name="content"]').addClass('ng-invalid-pattern'))(scope);
}
});
}
};
});
ここで実際のフィールドを選択し、クラスを変更して、正規表現が一致しない場合は無効にします。この方法では、[保存] ボタンも無効になります。これはドロップダウンで変更すると機能しますが、コンパイルされた要素が何らかの形で破損します。