2015-11-20 38 views
3

我可以訪問$ controllerProvider但如果我使用$控制器依賴注入不能訪問$控制器下面的方法

angular.module(MODULE_NAME, ['common']) 
    .config(['$routeProvider','$controllerProvider', 
     function($routeProvider, $controllerProvider) { 
     console.log($controllerProvider);//defined 
     console.log($controller);//undefined 
}]); 

,它給

Unknown provider: $controller 

但我需要訪問它,如何做到這一點

編輯

我需要這個,因爲我想檢查我的控制器是否存在。這裏是post從哪裏我使用此代碼

try { 
    $controller(controllerName); 
    listControlerName = MODULE_NAME+'ListController'; 
} catch (error) { 
    listControlerName = 'CommonListController'; 
} 

背景

我創建一個項目的架構。我的項目結構如下。

  1. 我有一個COMMON模塊。與ListController,EditController,ViewController
  2. 我有MOD1ListController,MOD1EditController,MOD1ViewController等MOD1,MOD2等一些其他模塊等。
  3. 那些模塊專用控制器從公共模塊擴展相應的控制器。現在

我的計劃是當一個新的模塊(鏌鋣)需要發展,那麼如果有一些額外的功能,那麼只有開發人員創建一個新的MODXListController該模塊通過繼承共同ListController。否則,他們不需要創造任何東西。

因此係統會檢查該模塊是否包含MODXListController。如果沒有,那麼系統將使用Common ListController。

我不想創建一個MODXListController繼承常見的ListController,但不做任何額外的更改。因爲我有大量的模塊將近25個,並且大部分都是共享相同的功能。

+0

您無法從您的配置中訪問'$ controller'。 –

+0

請提供上下文爲什麼不知道控制器是否存在。有更好的方法來做你想做的事,當然不是那樣。 – estus

+0

@estus我已更新上下文。 –

回答

1

沒有明確地繼承所有控制器(這是可以接受但冗長溶液),良好的備選方案是包裝控制器交換功能到mod-controller指令(類似於ng-controller),類似的東西:

angular.module('common', []) 
.constant('MODULE_NAME', 'Common') 
.constant('modControllers', []) 
.controller('CommonEditController', ...); 
.controller('CommonListController', ...); 
.directive('modController', function (MODULE_NAME, modControllers) { 
    return { 
    restrict: 'A', 
    scope: true, 
    priority: 500, 
    controller: function ($controller, $attrs, $scope) { 
     var ctrlName = (modControllers.indexOf($attrs.modController) >=0 ? MODULE_NAME : 'Common') + $attrs.modController; 

     angular.extend(this, $controller(ctrlName, { $scope: $scope })); 
    }); 
    }; 
}); 

angular.module('mod1', ['common']) 
.constant('MODULE_NAME', 'Mod1') 
.constant('modControllers', ['ListController']); 
.controller('Mod1ListController', function ($controller) { 
    angular.extend(this, $controller('CommonListController'); 
    ... 
}); 

當控制器應該在應用程序代碼而不是視圖中指定(即路由和指令控制器),類似的事情可以用控制器工廠完成。

angular.module('common') 
.provider('ctrlFactory', function (MODULE_NAME, modControllers) { 
    function factoryFn(ctrlName) { 
    return (modControllers.indexOf(ctrlName) >=0 ? MODULE_NAME : 'Common') + ctrlName; 
    }; 

    this.get = this.$get = factoryFn; 
}); 

可以注入指令,並作爲

... 
controller: ctrlFactory('ListController') 

由於它返回控制器的名稱,而不是$controller實例,僅取決於不變的服務(MODULE_NAME,modControllers)的事實,服務提供商也可以以同樣的方式用作服務實例中config塊聲明路由控制器:

... 
controller: ctrlFactoryProvider.get('ListController') 

因爲$controller沒有公開註冊控制器的列表,所以試圖捕捉它是一個自動解決方案,它是人們可能想要做的最後一件事情:除了它是一個黑客,它只是壓制可能的異常和損害可測試性。

+0

我喜歡這種方法。我一定會試試這個,讓你知道。感謝您寶貴的時間。 –

+0

還有一件事。我也用ng-view使用ng-router。這種方法是否會與此相符。我的網址pattarn是列表控制器的/ list或編輯/ id:編輯控制器。 –

+1

在原始問題中沒有提到它,它是一個重要的細節,因爲它改變了一切。查看更新。 – estus

0

在.config中,您只能使用提供者(例如$ routeProvider)。

在.run中,您只能使用服務實例(例如$ route)。

$控制器是不能在.config中使用的服務類型。

有關此詳細閱讀here.

this線程堆棧溢出的詳細討論,顯示了可注入等。

+0

那麼是否有可能檢查一個控制器是否存在或不在.config中? –

+0

看看這個線程http://stackoverflow.com/questions/19734565/how-to-check-if-an-angularjs-controller-has-been-defined –

+0

已經檢查過這個帖子,並在問題中的精神。有一個答案(由@trekforever發佈),建議更新角碼。有沒有更好的方法? –

0

你不能注入$controller到配置

雖然你可以使用以下服務來檢查,如果你的控制器定義。現在

angular.service('ControllerChecker', ['$controller', function($controller) { 
    return { 
    exists: function(controllerName) { 
     if(typeof window[controllerName] == 'function') { 
     return true; 
     } 
     try { 
     $controller(controllerName); 
     return true; 
     } catch (error) { 
     return !(error instanceof TypeError); 
     } 
    } 
    }; 
}]); 

你可以注入ControllerChecker並調用其exists(CtrlName)函數來檢查您的控制器是否被定義或沒有。

+0

如果我使用$控制器作爲依賴注入,它是給 未知的提供者:$控制器 –

+0

我已經看到該帖子發佈此問題之前。我也無法訪問該服務,所以我試圖直接訪問$控制器。 –

+0

同樣的方式我也無法訪問ControllerChecker服務。 :) –