Angularjs 向控制器内的工厂(单例)添加函数

Angularjs 向控制器内的工厂(单例)添加函数,angularjs,angular-ui-router,Angularjs,Angular Ui Router,我有一个名为search的工厂 我有许多名为searchactivitycontroller,SearchQuotaController等的控制器 工厂search是这些控制器向其添加函数实现的单例对象 问题是,名为SearchController的父控制器必须在工厂search内调用一个尚未实现的函数,因为子控制器在父控制器执行之后执行 看来我做错了什么 angular .module('app.search') .factory('search', search); sea

我有一个名为
search
的工厂

我有许多名为
searchactivitycontroller
SearchQuotaController
等的控制器

工厂
search
是这些控制器向其添加函数实现的单例对象

问题是,名为
SearchController
的父控制器必须在工厂
search
内调用一个尚未实现的函数,因为子控制器在父控制器执行之后执行

看来我做错了什么

angular
    .module('app.search')
    .factory('search', search);

search.$inject = ['$http', '$window', '$state', 'CONF', '$mdToast', 'USER_ROLES', 'USER_MODULES'];

function search($http, $window, $state, CONF, $mdToast, USER_ROLES, USER_MODULES) {

    var searchInfo;

    function updateQueryString(params) {
        $state.go(

            'search',

            {
                searchType: params.searchType,
                quotaId: params.quotaId,
                campaignName: params.campaignName,
                templateName: params.templateName,
                passId: params.passId,
                certId: params.certId
            },

            {notify: false}

        )
    }

    function getQuotaById(params) {
        var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId;
        return $http.get(reqPath);
    }

    function getCampaignById(params) {
        var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/campaigns/' + params.campaignName;
        return $http.get(reqPath);
    }

    function queryCampaigns(params) {
        var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/campaigns';
        return $http.get(reqPath);
    }

    function getTemplateById(params) {
        var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/campaigns/' + params.templateName;
        return $http.get(reqPath);
    }

    function queryTemplates(params) {
        var reqPath = CONF.apiPath + 'core/campaigns/' + params.campaignName + '/templates';
        return $http.get(reqPath);
    }

    function getPassById(params) {
        var reqPath = CONF.apiPath + 'core/passes/' + params.passId;
        return $http.get(reqPath);
    }

    function getPassbookById(params) {
        var reqPath = CONF.apiPath + 'core/passbookCert/' + params.certId;
        return $http.get(reqPath);
    }

    function queryPassbookCerts(params) {
        var reqPath = CONF.apiPath + 'core/quotas/' + params.quotaId + '/passbookCerts';
        return $http.get(reqPath);
    }

    //Global search logic
    //NEED TO RE-FACTOR
    function searchMasterFunction(params, obj) {

        if(params.searchType){
            search.changeSearchType(params.searchType);
        }

        updateQueryString(params);

        if(params.quotaId){
            search.getQuotaAndDisplayResult(params);
            // search.getPassbookCertsAndDisplayResult(params);

            search.updateQuotaIdInTemplateTab(params); //special - needs re-visit
        }

        if(params.quotaId && !params.campaignName){
            search.getCampaignsAndDisplayResult(params);
        }

        if(params.quotaId && params.campaignName && params.templateName){
            search.getCampaignAndDisplayResult(params);
            search.getTemplateAndDisplayResult(params);
        }else if(params.quotaId && params.campaignName){
            search.getCampaignAndDisplayResult(params);
            search.getTemplatesAndDisplayResult(params);
        }else if(params.quotaId && params.templateName){
            search.getTemplateAndDisplayResult(params);
        }

        if(params.campaignName){
            search.getTemplatesAndDisplayResult(params);
        }

        if(params.passId){
            search.getPassAndDisplayResult(params);
        }

        //getPassbookById

    }

    var search = {

        searchInfo: searchInfo,

        searchMasterFunction: searchMasterFunction,

        getQuotaById: getQuotaById,

        getCampaignById: getCampaignById,
        queryCampaigns: queryCampaigns,

        getTemplateById: getTemplateById,
        queryTemplates: queryTemplates,

        getPassById: getPassById,

        getPassbookById: getPassbookById,
        queryPassbookCerts: queryPassbookCerts
    };

    return search;


}
这是我的父控制器,它应该在工厂内调用searchmaster函数
search
,这样当查询字符串中有值时,它会根据
search
工厂内的逻辑自动填充任何搜索结果

angular
    .module('app.search')
    .controller('SearchController', SearchController);

SearchController.$inject = ['$state', 'search', '$scope', '$log'];

function SearchController($state, search, $scope, $log){

    $log.warn("Executing SearchController");

    var vm = this;

    vm.searchType = $state.params.searchType; //re-visit
    vm.tabs = ['quota', 'campaign', 'template', 'pass', 'cert'];

    vm.changeSearchTypeOnTabClick = changeSearchTypeOnTabClick;

    search.changeSearchType = changeSearchType;

    function changeSearchTypeOnTabClick(searchType) {
        $state.go('search', {searchType: searchType}, {notify: false});
    }

    function changeSearchType(searchType) {
        vm.searchType = searchType;
    }

    // this function call is what is causing the problem
    // search.searchMasterFunction($state.params);

}
下面是我的一个子控制器,它实现了search.getQuotaAndDisplayResult等功能

棱角的 .module('app.search') .controller(“SearchQuotaController”,SearchQuotaController)

所以问题是SearchQuotaController在SearchController之后运行,因此如果我尝试在SearchController中调用search.searchMasterFunction,它将无法正确执行,因为search.searchMasterFunction依赖于子控制器来执行,以便完成函数实现

任何帮助都将不胜感激。我已经考虑过$broadcast方法,但它似乎是一种黑客行为,而不是真正的解决方案


注:我之所以将子控制器的功能添加到
搜索
工厂中,是因为子控制器可以访问其本地
$scope

我不知道使用
$broadcast
是否是一种黑客行为,但从控制器向您的服务添加功能肯定感觉像是一种黑客行为。你可能想考虑用一种更可持续的方法重构整个事物。任何能让你远离从控制器向服务中添加功能的方法都比你现在的方法更可取。这是我能给你们的最好的建议。若我用这个方法呢?但即使这样,也会在工厂/服务中添加函数。我不知道使用
$broadcast
是否是一种黑客行为,但从控制器向服务中添加函数肯定感觉像是一种黑客行为。你可能想考虑用一种更可持续的方法重构整个事物。任何能让你远离从控制器向服务中添加功能的方法都比你现在的方法更可取。这是我能给你们的最好的建议。若我用这个方法呢?但即使这样,也会将函数隐式地添加到工厂/服务中。
SearchQuotaController.$inject = ['search', '$scope', '$log'];

function SearchQuotaController(search, $scope, $log){

    $log.info("Executing SearchQuotaController");

    var vm = this;

    vm.searchInfo;
    vm.quota;

    vm.searchBtnClick = searchBtnClick;

    search.getQuotaAndDisplayResult = getQuotaAndDisplayResult; //THIS LINE IS WHAT NEEDS ATTENTION. I'm adding a function into the `search` factory.

    function searchBtnClick(params){

        search.searchMasterFunction(params);

    };

    function getQuotaAndDisplayResult(params) {
        vm.searchInfo = params; //update fields in the Quota view

        search.getQuotaById(params).then(function(quota){
            vm.quota = quota.data; //update the quota object in the view
        });
    };

}