无法使用require将控制器和指令范围传递给子指令

时间:2015-04-30 01:37:14

标签: angularjs controller directive

我正在尝试将父控制器和父指令的控制器范围传递给子指令,但是面临一个错误,指出控制器不可用。这是一个插件

http://plnkr.co/edit/aahgOK9oFFjcP2y5VkVa?p=preview

HTML:

<div ng-controller="MainCtrl as mc">
    <new-dir>
      <data-customer-details customer="mc.customers[0]" logger="mc.logger()" version-age="{{mc.age}}"></data-customer-details>
    </new-dir>
  </div>

2 个答案:

答案 0 :(得分:1)

好的,所以我对你的傻瓜做了一点修补。我无法使用Controller As工作......我不得不将其更改为主控制器上的$ scope injection。然后我通过设置scope: true

在newDir上创建了一个新范围

您实际上并不需要MainCtrl,因为无论如何这些指令都自动成为该范围的子项。

我将'MainCtrl'更改为:

  angular.module('plunker').controller('MainCtrl', function ($scope) {

    $scope.name = 'World';

    $scope.customers = [{
      "name": "angularjs 1.4",
      "version": "1.4"
    }, {
      "name": "angularjs 1.3",
      "version": "1.3"
    }, {
      "name": "angularjs 1.2",
      "version": "1.2"
    }];

    $scope.age = 30;


    $scope.logger = function() {
      console.log('clicked');
    }

    $scope.ctrlScopeVariable = 'im in controller scope';
  })

对newDir的轻微更改:

function newDir (){
    return {
      scope: true, //you need this
      controller: function($scope){
        $scope.val= 'someval';
        console.log($scope.$parent.ctrlScopeVariable)
      },
      link: function(scope, el, attr, ctrl) {
       console.log(scope.$parent.name)
      }
    }
  }

最后一条指令:

  function CustomerDetails() {

    var directive = {
      scope: {
        customer: '=',
        logger: '&',
        myNewAge: '@versionAge'
      },
      restrict: 'EA',
      require: ['^newDir'],
      controllerAs: 'cd',
      templateUrl: 'customer-details.html',
      link: linkFunction,
      controller: function($scope){
        console.log($scope.$parent.$parent.ctrlScopeVariable);

        var cd = this;
        cd.newval = 'new val';
      }
    };

    function linkFunction(scope, elem, attributes, controllers, transclude) {
      console.dir(controllers);
      scope.fromMainCtrl = scope.$parent.$parent.ctrlScopeVariable
    }

    return directive;
  }

The Plunker

我添加了一个绑定到客户详细信息模板,该模板从主控制器传入$ scope.ctrlScopeVariable,因此您可以看到可以从子指令访问MainCtrl范围。

关于require,我认为相关文件在这里:

  

如果有必要引用控制器或任何绑定的功能   在模板中的控制器范围内,您可以使用该选项   controllerAs将控制器的名称指定为别名。该   指令需要定义要使用的此配置的范围。   这在使用指令的情况下特别有用   一个组件。

     

回顾myPane的定义,注意其中的最后一个参数   链接功能:tabsCtrl。当指令需要控制器时,它   接收该控制器作为其链接功能的第四个参数。   利用这一点,myPane可以调用addPane函数   myTabs。

基本上,您可以使用它来引用您需要访问某些功能的父控制器。值得注意的是,它可以在你给它的任何别名下作为你的链接函数的第四个参数。

修改 在这个Plunker中,我向newDir的控制器添加了一个函数,在CustomerDetail指令中需要newDir,然后在CustomerDetail链接函数中调用该函数:

CustomerDetails指令:

  //some stuff
  require: '^newDir',
  //some stuff
  link: function(scope, el, attr, newDirCtrl) {
    console.log(newDirCtrl.doubleNum(100));
  }

newDir控制器:

  controller: function($scope){
    this.doubleNum = function(num) {
      return num*2
    }
    // some stuff
  }

答案 1 :(得分:0)

首先,您需要将变量声明为回调函数:

var MainCtrlFn = function() { .... }

然后,您可以将其设置为angularJS的参数:

angular.module('plunker').controller('MainCtrl', MainCtrlFn);