AngularJS / Webix 表单 - 设置 ng-disabled 值后无法启用按钮?

AngularJS / Webix Form - Can't enable button after setting ng-disabled value?

控制器代码段下方显示的以下模板持续禁用 AngularJS 中的提交按钮。我曾尝试在 $scope.getTextValueAndValidate 函数的最后一行使用 $scope.$apply();,但是当该行执行时,我的表单会丢失所有条目(完全清除)。

如何解决此问题以启用我的按钮并防止在所有条目均有效后清除表单字段?

控制器代码段($scope.valid 检查是否填写了未显示的表单字段)

angular.module('Risk').controller('CreateRiskController', ['$http', '$resource', '$scope', '$state', '$window', '$timeout', '$interval', '$sce', 'CommonService', function($http, $resource, $scope, $state, $window, $timeout, $interval, $sce, CommonService){

  $scope.flags = {
    disabled: true
  }


  $scope.valid = function(){
            return($scope.risk.risktitle.trim() != '' &&
                   $scope.risk.riskstatement.trim() != '' &&
                   $scope.risk.context.trim() != '' &&
                   $scope.risk.closurecriteria.trim() != '' &&
                   $scope.risk.likelihood.trim() != '' &&
                   $scope.risk.technical.trim() != '' &&
                   $scope.risk.technical.trim() != '' &&
                   $scope.risk.cost.trim() != '' &&
                   !isNaN($scope.risk.likelihood) && Number($scope.risk.likelihood) >= 1 && Number($scope.risk.likelihood) <= 5 &&
                   !isNaN($scope.risk.technical) && Number($scope.risk.technical) >= 1 && Number($scope.risk.technical) <= 5 && 
                   !isNaN($scope.risk.schedule) && Number($scope.risk.schedule) >= 1 && Number($scope.risk.schedule) <= 5 &&
                   !isNaN($scope.risk.cost) && Number($scope.risk.cost) >= 1 && Number($scope.risk.cost) <= 5);
        }



  $scope.getTextValueAndValidate = function(obj, model, field){
        $scope.clearValidation(field);  
        CommonService.getTextValue(obj, model, 'risk', field); 
        $scope.validate(obj, field);
        valid = $scope.valid();
        $scope.flags.disabled = !valid;
  }
}]);

模板

<div id="formcontainer" ng-app="Risk" ng-controller="CreateRiskController" ng-init="init()">
    <div id="mycreateform" class="container" type="space" layout-padding="" ng-cloak="">   
        <init-risk />
        <form webix-ui="config" id="form" name="CreateRisk" role="form" ng-submit="valid() && submit()" novalidate>


 <table id="details" class="layout" border="1">
                <tr>
                    <td class="label">
                        Title
                    </td>
                    <td class="locked">
                        <div webix-ui="risktitleConfig" id="risktitle" name="risktitle" />
                    </td>
                </tr>
                <tr>    
                    <td class="label">
                        Risk Statement
                    </td>
                    <td class="locked">
                        <div webix-ui="riskstatementConfig" id="riskstatement" name="riskstatement" />
                    </td>
                </tr>
                <tr>
                    <td class="label">
                        Context
                    </td>
                    <td class="locked">
                        <div webix-ui="contextConfig" id="context" name="context" />
                    </td>
                </tr>
                <tr>
                    <td class="label">
                        Closure Criteria
                    </td>
                    <td class="locked">
                        <div webix-ui="closurecriteriaConfig" id="closurecriteria" name="closurecriteria" />
                    </td>
                </tr>
                 <!--tr class="text">
                        <td class="label">
                            Category
                        </td>
                        <td class="locked">
                             <div id="category" name="category" />
                        </td>
                  </tr-->
            </table>
            <h2>Initial Risk Assessment</h2>
            <div class="nested">
                <div class="info">
                    <table id="details" border="1">
                        <tr>
                            <td class="label">
                                Likelihood
                            </td>
                            <td class="locked">
                                <div webix-ui="likelihoodConfig" id="likelihood" name="likelihood" />
                            </td>
                        </tr>
                        <tr>
                            <td class="label" colspan="2">
                                Consequence
                            </td>
                        </tr>
                         <tr>
                            <td class="label margin-left">
                                Technical
                            </td>
                            <td class="locked">
                                <div webix-ui="technicalConfig" id="technical" name="technical" />
                            </td>
                        </tr>
                         <tr>
                            <td class="label margin-left">
                                Schedule
                            </td>
                            <td class="locked">
                                <div webix-ui="scheduleConfig" id="schedule" name="schedule" />
                            </td>
                        </tr>
                         <tr>
                            <td class="label margin-left">
                                Cost
                            </td>
                            <td class="locked">
                                <div webix-ui="costConfig" id="cost" name="cost" />
                            </td>
                        </tr>
                    </table>

            <button type="submit" ng-disabled="flags.disabled" class="raised primary">Create Risk</button>
        </form>
     </div>
</div>

指令(显示内部相关部分)

                function getLevelConfig(attr)
                {
                    var config = 
                    {
                        view:"text",
                        value: scope.risk[attr],      
                        on: {
                            "onChange": function(){var obj = this.eventSource || this; scope.getTextValueAndValidate(obj, scope, attr); assignRiskLevel();}
                        },
                        attributes: {
                            maxlength: 1
                        },
                        responsive: true,
                        width: "36",
                        height: "30",
                        required: true
                    };
                    return config;
                }

                function getTextConfig(attr)
                {
                    var config = 
                    {
                        view:"text",
                        value: scope.risk[attr],      
                        on: {
                            "onChange": function(){ var obj = this.eventSource || this; scope.getTextValueAndValidate(obj, scope, attr)}
                        },

                        responsive: true,
                        width: "520",
                        height: "30",
                        validate: webix.rules.isNotEmpty,
                        required: true
                    };
                    return config;
                }

                function getTextareaConfig(attr)
                {
                    var config = 
                    {
                        view:"textarea",
                        value: scope.risk[attr],
                        on: {                                  
                            "onChange": function(){var obj = this.eventSource || this; scope.getTextValueAndValidate(obj, scope, attr)},
                            //"onBlur": function(){scope.validate(scope.actionitem.actionitemstatement, 'actionitemstatement')}
                        },
                        responsive: true,
                        width: "520",
                        height: "97",
                        validate: webix.rules.isSelected,
                        required: true
                    };

                    return config;
                }

                function getSelectConfig(attr, options)
                {
                    var config = 
                    {
                        view: "richselect",
                        value: scope.risk[attr], 
                        options: options,
                        on: {
                            //"onChange": function(){var obj = this.eventSource || this; getValue(obj, 'assignor')},
                            "onChange": function(){var obj = this.eventSource || this; scope.getItemValueAndValidate(obj, scope, attr)}
                            //"onBlur": function(){scope.validate(scope.actionitem.assingor, 'assignor')}
                        },
                        responsive: true,
                        width: "520",
                        height: "30",
                        validate: webix.rules.isSelected,
                        required: true
                    };
                    return config;
                }


                scope.risktitleConfig = getTextConfig('risktitle');

                scope.riskstatementConfig = getTextareaConfig('riskstatement');

                scope.contextConfig = getTextareaConfig('context');

                scope.closurecriteriaConfig = getTextareaConfig('closurecriteria');

                scope.categoryConfig = getSelectConfig('category');

                scope.likelihoodConfig = getLevelConfig('likelihood');

                scope.technicalConfig = getLevelConfig('technical');

                scope.scheduleConfig = getLevelConfig('schedule');

                scope.costConfig = getLevelConfig('cost');

尽管没有直接使用 angular 指令,但我找到了一个有用的解决方案来解决我的问题。

How to set ng-disabled inside directive

根据建议修改我的解决方案很简单。

我在自己的指令中操纵了 DOM,而不是使用 AngularJS 的 ng-disabled 指令。

if (scope.valid())
     (document.querySelector('#submit')).removeAttribute('disabled');
else
     (document.querySelector('#submit')).setAttribute('disabled', 'disabled');

然后我在我的按钮中添加了一个 id 和一个在我的模板中初始化为 disabled 的 disabled 属性。

 <button id="submit" type="submit" disabled="disabled" class="raised primary">Create Risk</button>