如何在angular指令中共享范围并传递数据

时间:2014-12-10 03:35:03

标签: javascript angularjs angularjs-directive

在角度指令中我有这个

app.directive('myDir', function () {
  return {
    restrict: 'E',
    scope: true,
    template:'<div>{{myindex}}</div>',
    link: function(scope, element, attrs){
      console.log('test', scope.myindex)
    },
   controller: 'myDirController'
  };
})

我像这样使用

<my-dir> </my-dir>

现在因为我想在不同的模板中使用它,我有一个我想要调用的函数

// this is inside myDirController        
test: function($scope){
          $scope.myFunction();
        }

现在基本上我想打电话给$scope.myFunction();

如果在父控制器中定义了$scope.myFunction();,这样可以正常工作。

购买它不可重复使用,因为我想在其他控制器中调用$scope.myFunction2();

所以我想要一些东西,以便我可以在指令

中传递函数名

<my-dir fname="myFunction"> </my-dir>

并在我的指令中调用

问题是我不能使用隔离范围,因为我需要访问父$ scope

2 个答案:

答案 0 :(得分:2)

  

我想调用$ scope.myFunction();

     

[我的指令]不可重用,因为在我的其他控制器中我想调用$ scope.myFunction2();

     

所以我需要一些东西,以便我可以在指令中传递函数名称:

     

<my-dir fname="myFunction"> </my-dir>

1)自定义标记中的属性在链接函数中可用,因此您可以保存fname属性的值以供将来使用:

link: function(scope, element, attrs){
  scope.data = {fname: attrs.fname};
},

2)可以使用点表示法检索对象的属性,例如$scope.fname,但也可以使用数组表示法检索属性,例如$scope[fname],其中fname是一个字符串。如果$scope[fname]是一个函数,则可以通过编写$scope[fname]()

来执行它
app.controller('MyDirCtrl', function($scope) {
  $scope.test = function() {
    var fname = $scope.data.fname;
    $scope[fname]();  //fname property not found in current scope, so parent scope is searched
  };
});

...

<body ng-app="myApp">

  <div ng-controller="Ctrl1">
    <my-dir fname="funcInCtrl1"></my-dir>
  </div>

  <div ng-controller="Ctrl2">
    <my-dir fname="funcInCtrl2"></my-dir>
  </div>

...

var app = angular.module('myApp',[]);

app.controller('Ctrl1', ['$scope', function($scope) {
  $scope.funcInCtrl1 = function() {
    console.log('funcInCtrl1 called...');
  };
}]);

app.controller('Ctrl2', ['$scope', function($scope) {
  $scope.funcInCtrl2 = function() {
    console.log('funcInCtrl2 called...');
  };
}]);

app.controller('MyDirCtrl', ['$scope', function($scope) {
  $scope.test = function() {
    var fname = $scope.data.fname;
    $scope[fname]();
  };
}]);

app.directive('myDir', function () {
  return {
    restrict: 'E',
    scope: true,
    template:'<div ng-click="test()">click me</div>',

    link: function(scope, element, attrs){
      scope.data = {fname: attrs.fname};
    },

    controller: 'MyDirCtrl', 
  }
})

而且,这里的 Controller as 语法:

<body ng-app="myApp">

  <div ng-controller="Ctrl1 as ctrl1">
    <my-dir fname="ctrl1.funcInCtrl1"></my-dir>
  </div>

  <div ng-controller="Ctrl2 as ctrl2">
    <my-dir fname="ctrl2.funcInCtrl2"></my-dir>
  </div>

...

var app = angular.module('myApp',[]);

app.controller('Ctrl1', function() {
  this.funcInCtrl1 = function() {
    console.log('funcInCtrl1 called...');
  };
});

app.controller('Ctrl2', function() {
  this.funcInCtrl2 = function() {
    console.log('funcInCtrl2 called...');
  };
});

app.controller('MyDirCtrl', ['$scope', function($scope) {
  this.test = function() {
    var fnames = $scope.data.fname.split('.');
    var ctrl_name = fnames[0];
    var func_name = fnames[1];
    $scope[ctrl_name][func_name]();
  };
}]);

app.directive('myDir', function () {
  return {
    restrict: 'E',
    scope: true,
    template:'<div ng-click="mydirCtrl.test()">click me</div>',

    link: function(scope, element, attrs){
      scope.data = {fname: attrs.fname};
    },

    controller: 'MyDirCtrl', 
    controllerAs: 'mydirCtrl'
  }
})

答案 1 :(得分:0)

您可以使用工厂并使用此工厂创建使用特定功能的不同指令。

module.service('DirectiveFactory', function() {
  this.create = function(fn) {
    return {
      restrict: 'E',
      scope: true,
      template:'<div>{{myindex}}</div>',
      link: function(scope, element, attrs){
        console.log('test', scope.myindex)
      },
     controller: function($scope) {
       // your specific function
       fn();
     }
    };
  };
});

module.directive('my-dir-1', function(DirectiveFactory) {
  function fn1() {
    console.log('my special function call1');
  }
  return DirectiveFactory.create(fn1);
});

module.directive('my-dir-2', function(DirectiveFactory) {
  function fn1() {
    console.log('my special function call2');
  }
  return DirectiveFactory.create(fn2);
});

在您的模板中,您可以使用:

<my-dir-1></my-dir1>

<my-dir-2></my-dir2>