1

我有以下指令

directiveModule.directive('typeahead', function() {
    return {
        restrict: 'E',
        transclude: true,
        scope: 'isolate',
        templateUrl: 'assets/partials/common/typeahead.html' ,
        controller: ["$scope","$element","$attrs","$transclude", "Event", 
        function ($scope,$element,$attrs,$transclude, Event){
            console.log(eval($attrs.service + ".query();"));

            $scope.search = function(){ console.log("Searching for:" + $scope.selectedValue) };
            $scope.selectedValue = "";
            $scope.providedItems = []; 
        }],     
    };
});

使用以下模板:

<div>
<input ng-change="search()" ng-model="selectedValue" ng-click="log()" autocomplete="off" type="text"/>
<ul class=".typeahead">
    <li ng-repeat="item in providedItems">{{eval(item + "." + descriptor)}}</li>
</ul>

以及我认为的以下调用:

在指令中注入控制器时,我想让服务属性在运行时进行评估。所以它现在说

controller: ["$scope","$element","$attrs","$transclude", "Event", 
        function ($scope,$element,$attrs,$transclude, Event){

它会说类似于:

controller: ["$scope","$element","$attrs","$transclude", eval($attrs.service), 
        function ($scope,$element,$attrs,$transclude, eval($attrs.service)){

但是我无法从指令模块调用内的范围访问 $attrs。

如果有任何方法可以访问视图中声明的服务就足够了。请帮忙!

4

1 回答 1

5

一种解决方案是自己创建和绑定控制器。您所需要的只是注入$injector(为了动态解析服务)和$controller(为了动态解析控制器)。在您的链接功能中,您自己创建控制器:

link: function(scope, elm, attr) {
  $controller(function YourController($scope, dynamnicService) {
      dynamicService.query();
    }, {
      $scope: scope, 
      dynamicService: $injector.get($attr.service)
    }
  )
}

这里有一件很重要的事情。在此示例中,我正在考虑您的服务是元素属性中的字符串。如果它是范围内的字符串,由属性引用,那么您必须更改方法。您应该$attr.observe属性,并且在更改时,您应该获取服务$injector.get(...)并将其传递给控制器​​。您可以this.setService在控制器本身上创建一个方法,也可以在您的调用中创建方法$scope.setService。我更喜欢控制器,因为这与访问服务有关。使用第二种方法,您不需要手动创建控制器,您可以简单地公开此方法并从外部设置数据。

还有一个信息,你不应该从你的控制器中触摸 DOM。因此,无论如何,将$element, $attrand传递给控制器​​可能是一个坏主意。$transculde

查看关于$controller指令$injector的文档。

于 2013-07-24T11:58:43.210 回答