【问题标题】:Angularjs Form $valid not updateAngularjs Form $valid 不更新
【发布时间】:2015-07-28 14:35:02
【问题描述】:

我有一个自定义指令,它是一个 ng-modal 窗口。我的问题是,当我在代码中设置其中一个字段(患者 ID)时,即使所有必填字段都为真,表单的 $valid 也不会更新为真。当我通过 UI 更新 patientid 字段时,$valid 会正确更新。由于在当前情况下禁用了相关字段,因此我不能依赖用户手动更新该字段。作为快速修复,我使用 $error.required 来禁用保存按钮,但希望以正确的方式进行。

'use strict';
var mod
try {
    mod = angular.module('DCI');
}
catch (err) {
    mod = angular.module('DCI', []);
}


mod.directive('labResultEntry', function () {
    return {
        restrict: 'E',
        scope: {
            labRanges: '=',
            show: '=',
            patientList: '=',
            editResult: '=',
            saveLabCallback: '='
        },
        replace: true,
        link: function (scope, element, attrs) {
            scope.dialogStyle = {};
            scope.result = {};
            scope.autoComplateControl1 = {};
            scope.autoComplateControl2 = {};
            scope.result.SensitiveData = 'N';
            scope.editdisable = scope.isOpen = false;
            var rootScope = scope.$parent;


            if (attrs.saveResultCallback)
                scope.saveResultCallback = attrs.saveResultCallback
            if (attrs.width)
                scope.dialogStyle.width = attrs.width;
            if (attrs.height)
                scope.dialogStyle.height = attrs.height;

            scope.$watch('show',
                            function () {
                                if (scope.show == true) {
                                    if (scope.editResult != undefined) {
                                        scope.editdisable = true;
                                        scope.autoComplateControl1.insertInput(rootScope.patientName);
                                        scope.result.patientId = rootScope.patientId;
                                        scope.result.sampledate = scope.editResult.sampledate;
                                        scope.result.TestCode = scope.editResult.TestCode
                                        scope.result.Result = parseFloat(scope.editResult.Result);
                                        scope.result.LabResultId = scope.editResult.LabResultId;

                                        angular.forEach(scope.labRanges, function (test) {
                                            if (test.TestCode == scope.editResult.TestCode) {
                                                scope.result.TestDescription = test.TestDescription;
                                                scope.result.ShortName = test.ShortName;
                                                scope.result.MaxValue = test.MaxValue;
                                                scope.result.MinValue = test.MinValue;
                                                scope.result.UOM = test.UOM;
                                                scope.autoComplateControl2.insertInput(test.TestDescription);
                                            }
                                        })
                                    }
                                    else
                                        scope.editdisable = false;
                                    SetPatientId();
                                }
                            }, true);

            function SetPatientId() {
                if (rootScope.patientId) {
                    scope.autoComplateControl1.insertInput(rootScope.patientName);
                    rootScope.safeApply(function(){
                        scope.result.patientId = rootScope.patientId;
                    });
                }
                else {
                    if (scope.autoComplateControl1.clearnInput != undefined) {
                        scope.autoComplateControl1.clearnInput();
                    }
                    scope.result.patientId = undefined;
                }
            };

            function reset() {
                scope.result = {};
                scope.result.SensitiveData = 'N';
                SetPatientId();
                scope.autoComplateControl2.clearnInput();
                scope.editResult = undefined;
            };

            scope.hideModal = function () {
                reset();
                scope.show = false;
            };

            scope.autoCompleteSelect = function (item) {
                if (item) {
                    scope.result.MaxValue = item.description.MaxValue;
                    scope.result.MinValue = item.description.MinValue;
                    scope.result.UOM = item.description.UOM;
                    scope.result.ShortName = item.description.ShortName;
                    scope.result.TestCode = parseFloat(item.description.TestCode, 10);
                    scope.result.TestDescription = item.description.TestDescription;
                }
            };

            scope.open = function ($event) {
                $event.preventDefault();
                $event.stopPropagation();
                scope.isOpen = true;
            };

            scope.selectPatient = function (item) {
                if (item) {
                    var found = false;
                    angular.forEach(scope.patientList, function (itemp) {
                        if (item.originalObject.PatientId = itemp.PatientId)
                            found = true;
                    });

                    if (found)
                        scope.result.patientId = item.originalObject.PatientId;
                }
            };

            scope.LookUpTestCode = function () {
                angular.forEach(scope.labRanges, function (test) {
                    if (test.TestCode == scope.result.TestCode) {
                        scope.result.TestDescription = test.TestDescription;
                        scope.result.ShortName = test.ShortName;
                        scope.result.MaxValue = test.MaxValue;
                        scope.result.MinValue = test.MinValue;
                        scope.result.UOM = test.UOM;
                        scope.autoComplateControl2.insertInput(test.TestDescription);
                    }
                })
            };

            scope.saveResult = function () {
                var result = {};
                angular.copy(scope.result, result);
                result.labLocation = "002060";
                scope.saveLabCallback(result);
                scope.hideModal()
            };
        },
        template: "HTML code below as single string"
<div class="ng-modal colored-header" ng-show="show">
    <div class="ng-modal-overlay" ng-click="hideLabModal()"></div>
    <div class="ng-modal-dialog md-content" ng-style="dialogStyle">
        <div class="modal-header">
            <div class="ng-modal-close" ng-click="hideModal()">X</div>
            <h3>Lab Result</h3>
        </div>
        <div class="ng-modal-dialog-content">
            <form name="labEntry" role="form" class="modal-body">
                <div angucomplete-alt id="ex2" placeholder="Patient*" maxlength="50" pause="400" selected-object="selectPatient" local-data="patientList" field-required="!result.patientId" 
                     field-required-class="ng-invalid"  search-fields="PatientName" disable-input="editdisable" title-field="PatientName" minlength="4" input-class="form-control-small form-control" match-class="highlight" control="autoComplateControl1" />
                <br />
                <input class="form-control col-xs-9 col-sm-9 col-md-9" style="margin-top: 3px; margin-bottom: 3px;" type="text" ng-disabled="true" ng-model="result.labLocation" placeholder="OTHER  (LAB)" />
                <br />
                <br />
                <br />
                <input ng-style="{ 'border-color' : (labEntry.TestCode.$valid == false ? 'red' : 'null') }" name="TestCode" class="form-control col-xs-9 col-sm-9 col-md-9" ng-disabled="editdisable" ng-required="!result.TestCode" ng-model="result.TestCode" placeholder="Test code*" ng-blur="LookUpTestCode()" />
                <br />
                <br />
                <br />
                <div angucomplete-alt id="ex3" placeholder="Description*" maxlength="50" pause="400" selected-object="autoCompleteSelect" local-data="labRanges"
                        search-fields="TestDescription" disable-input="editdisable" title-field="TestDescription" minlength="4" input-class="form-control form-control-small" match-class="highlight" control="autoComplateControl2" />
                <br />
                <input ng-style="{ 'border-color' : (labEntry.Result.$valid == false ? 'red' : 'null') }" style="margin-top: 3px; margin-bottom: 3px;" name="Result" class="form-control col-xs-9 col-sm-9 col-md-9" ng-required="!result.Result" ng-model="result.Result" placeholder="Result*" />
                <br />
                <br />
                <br />
                <p class="input-group">
                    <input name="sdate" ng-style="{ 'border-color' : (labEntry.sdate.$valid == false ? 'red' : 'null') }" class="input-group-addon form-control" is-open="isOpen" datepicker-popup="MM/dd/yyyy" ng-required="!result.sampledate"  ng-model="result.sampledate"
                            placeholder="Sample Date*" />
                    <span class="input-group-btn">
                        <span class="input-group-addon btn btn-primary" ng-click="open($event)"><i class="glyphicon glyphicon-th"></i></span>
                    </span>
                </p>
                <input class="col-xs-6 col-sm-6 col-md-6" type="text" ng-disabled="true" ng-model="result.MinValue" placeholder="Range Min" />
                <input class="col-xs-6 col-sm-6 col-md-6" type="text" ng-disabled="true" ng-model="result.MaxValue" placeholder="Range Max" />
                <br />
                <br />
                <input class="col-xs-6 col-sm-6 col-md-6" type="text" ng-disabled="true" ng-model="result.UOM" placeholder="UOM" />
                <br />
                <br />
                <input type="checkbox" class="iCheck" icheck ng-model="result.SensitiveData" ng-true-value="'Y'" ng-false-value="'N'" /> Sensitive Data
                <br />
                <br />
                <textarea class="form-control" rows="4" placeholder="comments..." ng-model="result.Comment"></textarea>
            </form>
            <div class="modal-footer">
                <button type="button" class="btn btn-flat md-close" ng-click="hideModal()">Cancel</button>
                <button type="button" class="btn btn-flat btn-success" ng-disabled="!labEntry.$valid" ng-click="saveResult()">Save</button>
            </div>
        </div>
    </div>
</div>

【问题讨论】:

    标签: javascript jquery angularjs validation


    【解决方案1】:

    digest() 方法可能会有所帮助:

    将此函数添加到末尾,并在设置完所有内容后从任何将值更改为范围的函数调用它:

    function digest() {
        if ( scope.$$phase !== '$apply' && scope.$$phase !== '$digest' ) {
            scope.$digest();
        }
    }
    

    您可以在 Angulars 网站上获取有关摘要功能的更多信息:

    处理当前作用域及其子作用域的所有观察者。 因为观察者的监听者可以改变模型,所以 $digest() 保持 调用观察者,直到没有更多的听众被触发。

    https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest

    我希望这会有所帮助。

    【讨论】:

    • 我包装的更改是一个 safeApply() 函数。它调用 $apply()。但这无济于事。
    • 嗯,好吧,我明白了。然后,我会检查您应用它的范围是否正确。在那之后我就没主意了;-)
    【解决方案2】:

    想通了。这是我使用的 Autocomplete-alt 指令的问题。更新到 1.1.0 并解决了。

    【讨论】:

      猜你喜欢
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 1970-01-01
      • 2013-10-23
      相关资源
      最近更新 更多