将通用控制器功能提取到基础控制器

时间:2015-11-08 06:34:51

标签: angularjs refactoring angularjs-service angularjs-controller

我正在处理的网络应用有一个Person实体的视图。我们有几个控制器对该人的数据执行CRUD操作(例如电话号码,电子邮件地址等)。反过来,这些控制器包含在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的新手,所以我想知道如何使用架构应用来实现可维护性。

编辑:我找到了这篇文章。这适合我的用例吗? http://jasonwatmore.com/post/2014/03/25/AngularJS-A-better-way-to-implement-a-base-controller.aspx

2 个答案:

答案 0 :(得分:0)

您可以使用如下代码片段创建工厂(服务):

$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!";
    }

}

答案 1 :(得分:0)

我要继续说原型继承可能是你最好的选择。 这是我用来参考的文章 http://blog.mgechev.com/2013/12/18/inheritance-services-controllers-in-angularjs/

因此,如果您想创建一个托管共享数据的服务(一个好主意),您仍然可以这样做,但只需要在“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]);