【问题标题】:Custom validation via child control通过子控件自定义验证
【发布时间】:2017-04-18 19:00:01
【问题描述】:

所以我在一个包含它自己的表单元素和按钮的指令中工作,但是所有控件都必须被嵌入。此特定视图的模型包含一个总容量属性和一个作为隔间(单独实体)集合的属性。每个隔间都有自己的容量。如果/当总容量不等于所有隔间的总容量时,我已经有一个功能将在视图上显示错误。这里的问题是,由于我的所有控件都被嵌入(并且我不应该修改父指令),我不知道是否/如何使用相同的函数将表单标记为无效以禁用保存按钮。我想知道是否有一种解决方案(希望不涉及自定义指令或服务),如果表达式返回 true,我可以将父表单设置为无效。

** 更新 **

对不起,我想我第一次解释得倒过来了。因此,这将很好地代表 html 中正在发生的事情。 (而且在此之前我没有太多使用stackoverflow,所以请耐心等待)

编辑页面指令:

<div>
<form name="editForm">
<ng-transclude>

</ng-transclude>
<a class="btn btn-success">Save</a>
<a class="btn btn-danger">Cancel</a>
</form>
</div>

查看此特定编辑:

<edit-page>
    <uib-tabset>
        <uib-tab>
            <!--Total Capacity input-->
            <input type="text" numeric="{min:1, format:'#,###.#'}" ng-model-options="{updateOn: 'blur'}" class="form-control" id="tcCapacity" name="tcCapacity" data-ng-required="true" ng-model="vm.dataContext.entity.TotalCapacity" />
            <!--End Total Capacity-->
        </uib-tab>
        <uib-tab>
            <table>
                <tr><thead><th>...</th><th>Capacity</th><th>(Buttons for compartment add/remove)</th></thead></tr>
                <tr ng-repeat="compartment in vm.dataContext.entity.TrailerConfigCompartments">
                    <td width="200">{{compartment.Sequence}}</td>
                    <!--Important input under this-->
                    <td><input type="text" numeric="{min:0, format:'#,###.#'}" class="form-control" ng-model="compartment.Capacity" data-ng-required="true" /></td>
                    <!--Important input above-->
                    <td align="right" style="padding-right:30px;">
                        <a class="btn" style="padding: .7em; color: black;" ng-click="vm.addCompartment(compartment.Sequence + 1)">
                            <span uib-tooltip="New compartment at sequence {{compartment.Sequence + 1}}" class="btn-edit" style='margin-left:5px'><span class="glyphicon glyphicon-plus" style="margin-top:3px"></span></span>
                        </a>
 &nbsp;&nbsp;
                        <a class="btn" style="padding: .7em; color: black;" ng-click="vm.removeCompartment(compartment)">
                            <span uib-tooltip="Remove compartment" class="btn-edit" style='margin-left:5px'><span class="glyphicon glyphicon-minus" style="margin-top:3px"></span></span>
                        </a>
                    </td>
                </tr>
            </table>
        </uib-tab>
    </uib-tabset>
</edit-page>

【问题讨论】:

    标签: angularjs validation angularjs-directive


    【解决方案1】:

    如果我理解正确,你有类似的东西

    HTML

     <div data-ng-controller="FormController as vm">
        <form class="foo form">
    
           <input type="text"> // some inputs
           <input type="text"> // some inputs
    
           <transcluded-directive>
    
                 <button class="foo button-to-disable">Do something</button> // button that should be disabled
    
           </transcluded-directive>
    
    
        </form>
     </div>
    

    JS

    .controller("FormController", function($scope) {
    
       var vm = this;
    
       vm.validateTotalCapacity = function () {
          // validation stuff
       }
    
    });
    

    所以我认为你可以这样做:

    HTML

     <div data-ng-controller="FormController as vm">
        <form class="foo form  {{vm.validateTotalCapacity() ? '' : 'form-has-errors'}}" >
    
           <input type="text"> // some inputs
           <input type="text"> // some inputs
    
           <transcluded-directive>
    
                 <button class="foo button-to-disable">Do something</button> // button that should be disabled
    
           </transcluded-directive>
    
    
        </form>
     </div>
    

    看我把你的表单验证器放在&lt;form class="foo form"&gt; 并为错误类设置条件

    CSS

      .form-has-errors .button-to-disable {
           pointer-events: none;
           cursor: default;
           opacity: 0.5 
           // or your custom disabled styles
      }
    

    更新

    我明白了,但我相信你可以试试这个:

    HTML

        <div>
            <form name="editForm"  class="{{editForm.$valid ? '' : 'form-has-errors '}}">
                <ng-transclude>
    
                </ng-transclude>
                <a class="btn btn-success">Save</a>
                <a class="btn btn-danger">Cancel</a>
            </form>
        </div>
    

    【讨论】:

    • 嘿,谢谢你这么快的回复,看来我倒过来解释了。我更新了这个问题,让您对我正在使用的内容有一个很好的了解
    【解决方案2】:

    所以我意识到我误解了 angularjs 的 customValidation 部分。我认为我必须为验证创建的任何指令都必须添加到表单元素本身。同样,我认为设置起来会比实际要困难得多。

    供将来参考:

    1.) 创建一个指令并将其限制为一个属性

    2.) 该指令需要 ngModel

    3.) 设置链接功能:

    link: function(scope, elem, attrs, ngModel) {....}
    

    4.) 向要验证的控件的 $validators 对象添加一个函数。在您的链接功能中执行此操作。例如:

    link: function(scope, elem, attrs, ngModel) {
        ngModel.$validators.validationFn = function(value) {
            //Where value is the current value of the control
    
            //In my case, where I want to compare value to the combined value of other
            //compartments I would send in whatever data I wanted via the scope property of 
            //this directive and compare the two in this function 
        }
    }
    

    5.) 如果控制有效则返回 true,反之亦然

    就是这样。

    如果您想访问此验证器以显示错误消息:

    ng-show="vm.arbitraryInput.$error.validationFn"
    

    请记住,现在如果它返回 true,那么输入是无效的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      相关资源
      最近更新 更多