AngularJS普通控制器功能 - 混合 - 在需要或$ rootScope定义在哪里?控制器、定义、普通、功能

2023-09-13 04:51:47 作者:三分醒七分醉

我使用AngularJS的V1.2.0 RC2,想知道什么是向多个控制器提供常用功能的最佳方法。

I am using v1.2.0 rc2 of AngularJS and want to know what is the best method to provide common functionality to multiple controllers.

我有我想在所有的控制器使用下面的验证函数编辑模型:

I have the following validation functions that I want to use in all controllers that edit a model:

$scope.canSave = function (formController) {
    return formController.$dirty && formController.$valid;
};

$scope.validationClasses = function (modelController) {
    return {
        'has-error': modelController.$invalid && modelController.$dirty,
        'has-success': modelController.$valid && modelController.$dirty
    };
};

我要保持我的控制器干,所以我定义了一个工厂如下:

I want to keep my controllers DRY so I defined a factory as follows:

angular.module('myModule', [])
    .factory('validationFactory', [function () {
        return {
            validationClasses: function (modelController) {
                return {
                    'has-error': modelController.$invalid && modelController.$dirty,
                    'has-success': modelController.$valid && modelController.$dirty
                };
            },
            isFormValid: function (formController) {
                return formController.$dirty && formController.$valid;
            }
        };
    }]);

起初,我只是混出厂到有需要的控制器如下:

Initially, I just mixed the factory into the controllers that needed it as follows:

$scope.canSave = validationFactory.isFormValid;

$scope.validationClasses = validationFactory.validationClasses;

但我意识到我可以在模块的run方法将它们添加到$ rootScope如下:

But I realised I could add them to the $rootScope in the module's run method as follows:

angular.module('myModule', [])
    .run([
        '$rootScope',
        'validationFactory',
        function ($rootScope, validationFactory) {
            $rootScope.canSave = $rootScope.canUpdate = validationFactory.isFormValid;
            $rootScope.validationClasses = validationFactory.validationClasses;
        }]);

现在他们每个控制器都不加区别地提供有接线少了起来做的。

Now they are available in every controller indiscriminately and there is less wiring up to do.

该功能在视图模板中使用如下:

The functions are used in the view templates as follows:

<form name="questionForm" novalidate>
    <div class="form-group" ng-class="validationClasses(questionForm.question)">
        <label for="questionText" class="control-label">Text</label>
        <input type="text" ng-model="question.text" name="question"
               id="questionText" class="form-control" required/>
        <span ng-show="questionForm.question.$error.required"
              class="help-block">Question text is required</span>
    </div>
    ...
    <div class="form-group" ng-switch on="action">
        <button type="button" ng-switch-when="New" ng-click="save()" 
                ng-disabled="!canSave(questionForm)" 
                class="btn btn-primary">Save</button>
        <button type="button" ng-switch-default ng-click="update()" 
                ng-disabled="!canUpdate(questionForm)" 
                class="btn btn-primary">Update</button>
        <button type="button" ng-click="cancel()"
                class="btn btn-default">Cancel</button>
    </div>
</form>

我的问题是:

我应避免添加常用功能到$ rootScope?如果是这样,有什么陷阱?是它更好地混合,共同的功能仅在必要?有没有实现相同结果的更好的办法?

更新的解决方案

我选择使用自定义指令,而不是添加功能到$ rootScope其​​中有一个关于它的讨厌气味。

I opted to use custom directives instead of adding functions to the $rootScope which had a nasty smell about it.

我创建自定义属性验证级换=&LT; input.name&gt;中残疾时,无效这样的标记看起来是这样的:

I created custom attributes validation-class-for="<input.name>" and disabled-when-invalid so the markup looks like this:

<div class="form-group" validation-class-for="question">
    <label for="questionText" class="control-label">Text</label>
    <input type="text" ng-model="question.text" name="question"
           id="questionText" class="form-control" required/>
    <span ng-show="questionForm.question.$error.required"
          class="help-block">Question text is required</span>
</div>

<button type="button" ng-click="save()" disabled-when-invalid 
    class="btn btn-primary">Save</button>

该指令只是需要一个形式的祖先,看一个函数来确定的状态。

The directives simply require a form ancestor and watch a function to determine state.

angular.module('myModule', [])
    .directive('validationClassFor', function () {
        return {
            require: '^form',
            link: function (scope, element, attributes, formController) {
                scope.$watch(function () {
                    var field = formController[attributes.validationClassFor];
                    if (field.$invalid && field.$dirty) {
                        element.removeClass('has-success').addClass('has-error');
                    } else if (field.$valid && field.$dirty) {
                        element.removeClass('has-error').addClass('has-success');
                    } else {
                        element.removeClass('has-error').removeClass('has-success');
                    }
                });
            }
        };
    })
    .directive('disabledWhenInvalid', function () {
        return {
            require: '^form',
            link: function (scope, element, attributes, formController) {
                scope.$watch(function () {
                    return formController.$dirty && formController.$valid;
                }, function (value) {
                    element.prop('disabled', !value);
                });
            }
        };
    });

现在没有必要为验证工厂任

Now there is no need for the validation factory either.

推荐答案

你如何使用这个validationFactory?难道是改变的提交按钮的外观?如果是这样,我建议对按钮本身创建自定义组件,并有部分参考validationFactory。

How are you using this validationFactory? Is it to change the appearance of for submit buttons? If so, I'd suggest creating custom components for the buttons themselves, and have the component reference the validationFactory.

 
精彩推荐
图片推荐