Angularjs Form $有效不更新

时间:2015-07-28 14:35:03

标签: javascript jquery angularjs validation

我有一个自定义指令,它是一个ng-modal窗口。我的问题是当我在代码中设置显示的一个字段(patientId)时,即使所有必填字段都为真,表单的$ valid也不会更新为true。当我通过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>

2 个答案:

答案 0 :(得分:0)

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

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

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

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

  

处理当前范围及其子项的所有观察者。   因为观察者的监听器可以改变模型,所以$ digest()保持不变   打电话给观察者直到没有更多的听众开枪。

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

我希望这会有所帮助。

答案 1 :(得分:0)

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