Angularjs 将通用控制器功能提取到基本控制器中

Angularjs 将通用控制器功能提取到基本控制器中,angularjs,refactoring,angularjs-service,angularjs-controller,Angularjs,Refactoring,Angularjs Service,Angularjs Controller,我正在使用的web应用程序有一个个人实体的视图。我们有多个控制器对此人的数据(如电话号码、电子邮件地址等)执行CRUD操作。反过来,这些控制器包含在FormController中,FormController收集所有要执行的操作,并将它们实际存储在数据库中 例如,电子邮件的添加操作的代码如下所示: angular.module('people').controller('emailsFormController', ['$scope', function ($scope) {

我正在使用的web应用程序有一个
个人
实体的视图。我们有多个控制器对此人的数据(如电话号码、电子邮件地址等)执行CRUD操作。反过来,这些控制器包含在FormController中,FormController收集所有要执行的操作,并将它们实际存储在数据库中

例如,电子邮件的添加操作的代码如下所示:

angular.module('people').controller('emailsFormController', 
    ['$scope', 
    function ($scope) {

    $scope.emails = [];
    $scope.emailErrorMessage = "";
    $scope.newEmailAddress = ""; //this is set in the view

    $scope.addNewEmail = function () {
        if (!emailExists($scope.newEmailAddress)) {
            var newEmail = {
                Dto: {
                    Id: -1,
                    EmailAddress: $scope.newEmailAddress,
                    EmailDescription: "No Description",
                },
                State: "Add"
            };
            $scope.emails.push(newEmail);
        }
        else {
            $scope.emailErrorMessage = "The email already exists!";
        }
    };
};
可以想象,添加电话号码的代码基本相同。 (变量名和DTO对象除外…)

如何将这一常见功能提取到基本(控制器|服务)中?哪个更合适?我是Angular的新手,所以我想知道如何为可维护性构建应用程序


编辑:我找到了这篇文章。这适合我的用例吗

您可以创建一个工厂(服务),其代码片段如下:

$scope.addNewFeature = function ( type ) {

    switch ( type ) {

        default:
        case "email": 
            if (!emailExists($scope.newEmailAddress)) {
                var newEmail = {
                    Dto: {
                        Id: -1,
                        EmailAddress: $scope.newEmailAddress,
                        EmailDescription: "No Description",
                    },
                    State: "Add"
                };
                $scope.emails.push(newEmail);
            }
            else {
                $scope.emailErrorMessage = "The email already exists!";
            }

            break;

       case "phone":
            if (!phoneExists($scope.newphoneAddress)) {
                var newPhone = {
                    Dto: {
                        Id: -1,
                        phoneNumber: $scope.newPhoneNumber,
                        phoneDescription: "No Description",
                    },
                    State: "Add"
                };
                $scope.phones.push(newPhone);
            }
            else {
                $scope.phoneErrorMessage = "The phone already exists!";
            }

            break;

    }

};
您还可以创建动态函数执行,但这需要使用
eval()
,没有人喜欢这样做。:)

另一种方法是使用一个用于添加项的公共函数,以及一些单独的函数来检查项类型并以这种方式修改请求

var getItemType = function( checkVar ) {

    return ( checkVar.indexOf( '@' ) > -1 && checkVar.indexOf( '.' ) > -1 ) ? "email" : "phone"; // Very primitive; just an example.

}

var itemExists = function( item ) {

    return (

        ( getItemType( item ) === "phone" ) ?
            // Check for phone :
            // Check for email

    );

}

$scope.addNewItem = function ( item ) {

    if (!itemExists( item )) {
        var newItem = {
            Dto: {
                Id: -1,
                ItemAddress: $scope.newItemAddress,
                ItemDescription: "No Description",
                ItemType: getItemType( item )
            },
            State: "Add"
        };
        $scope.items.push(newItem);
    }
    else {
        $scope.itemErrorMessage = "The item already exists!";
    }

}
变形函数:

var getItemType = function( checkVar ) {

    return ( checkVar.indexOf( '@' ) > -1 && checkVar.indexOf( '.' ) > -1 ) ? "email" : "phone"; // Very primitive; just an example.

}

var itemExists = function( item ) {

    return (

        ( getItemType( item ) === "phone" ) ?
            // Check for phone :
            // Check for email

    );

}

$scope.addNewItem = function ( item ) {

    var itemExistsF = theFirstFunctionYouWant;

    if ( getItemType( item ) === "phone" ) {
        itemExistsF = theFunctionYouWant;
    } 

    if (!itemExistsF( item )) {
        var newItem = {
            Dto: {
                Id: -1,
                ItemAddress: $scope.newItemAddress,
                ItemDescription: "No Description",
                ItemType: getItemType( item )
            },
            State: "Add"
        };
        $scope.items.push(newItem);
    }
    else {
        $scope.itemErrorMessage = "The item already exists!";
    }

}

我要继续说,原型遗传可能是你最好的选择。 这是我用来参考的文章

因此,如果您想创建一个服务来承载共享数据(一个好主意),您仍然可以这样做,但只需要在“mainFormController”中初始化它。通过让子控制器从该控制器继承,它们将具有引用设置

function mainFormController($scope){
    //Core stuff up here
    $scope.OverrideMe = function(){

    };
};

function emailsFormController($scope){
    this.mainFormController($scope);

    $scope.addNewEmail = function () {
        if (!emailExists($scope.newEmailAddress)) {
            var newEmail = {
                Dto: {
                    Id: -1,
                    EmailAddress: $scope.newEmailAddress,
                    EmailDescription: "No Description",
                },
                State: "Add"
            };
            $scope.emails.push(newEmail);
        }
        else {
            $scope.emailErrorMessage = "The email already exists!";
        }
    };

    //OverrideExample
    $scope.OverrideMe = function(){
        //new override function code goes here
    };
};

emailsFormController.prototype = Object.create(mainFormController);

angular.module('people').controller('emailsFormController', ['$scope',emailsFormController]);

我喜欢第二种方法。但是,例如,有可能覆盖“itemExists”方法吗?是的!但这取决于你到底想怎么改变它。看一下编辑,