2013-08-27 71 views
16

我想分享以下两个指令之间的$scope如何在AngularJS中的两个指令之间共享范围?

One23SRCApp.directive('directive1',function() { 
    return { 
     restrict: "A", 
     scope:true, 
     link: function (scope, element, attrs) { 
      scope.tablename = "table"; 
     } 
    }; 
}); 


One23SRCApp.directive('directive2',function() { 
    return { 
     restrict: "A", 
      link: function (scope, element, attrs) { 
      var tablename = scope.tablename; 
     } 
    }; 
}) 

在HTML,我有:

<input type="text" directive2 placeholder="Search Models..."> 

<table directive1> 
    <tr> 
    <td>column1</td> 
    <td>column1</td> 
    </tr> 
</table> 

我已经创建了一个名为“指令1”与隔离范围的指令,分配名称“表”到scope.tablename属性。我无法在其他指令中访问此范围属性。

那么我怎样才能访问另一个指令的范围?

+0

如何在HTML中被组织的指示? – Chandermani

+0

@chnadermani我已更新我的问题,我已对不同元素应用指令。 – Shivkumar

回答

5

对于需要跨指令同步的项目,您可以执行$rootScope.$broadcast

或者您可以将一个对象传递给您的指令1隔离范围,该范围将充当通信机制。如果您更改tablename等子属性,此对象会影响父范围。

喜欢的东西

One23SRCApp.directive('directive1',function() { 
    return { 
     restrict: "A", 
     scope:{tableconfig:'='}, 
     link: function (scope, element, attrs) { 
      scope.tableconfig.tablename= "table"; 
     } 
    }; 
}); 


One23SRCApp.directive('directive2',function() { 
    return { 
     restrict: "A", 
      link: function (scope, element, attrs) { 
      var tablename = scope.tableconfig.tablename; 
     } 
    }; 
}) 

的HTML变得

<table directive1 tableconfig='tableconfig'> 
    <tr> 
    <td>column1</td> 
    <td>column1</td> 
    </tr> 
</table> 

你的控制器应该有这样的对象定义

$scope.tableconfig={};

+12

使用$ rootScope是一种反模式 –

+0

这是一种不好的做法,如果您只希望在指令之间共享相同的作用域,则您的隔离作用域会受到污染。 –

+0

@Chandermani。我坚持有关这个问题非常糟糕。我是新的角可以看到这个链接http://stackoverflow.com/questions/43521905/set-one-showrangeselector-for-dyo-dygraph谢谢 –

16

我的建议是使用共享资源,例如一项服务。服务是单例,意味着每个服务只有一个实例,因此您可以使用它们在指令,控制器,范围之间共享数据,甚至在通过路由更改页面时也是如此。

你会定义资源的服务是这样的:

app.factory("MyResource",function(){ 
    return {}; 
}); 

你可以再注入该服务到您的指令(和控制器如果需要的话),并使用它像这样。

One23SRCApp.directive('directive1', ['MyResource', function(MyResource) { 
    return { 
     restrict: "A", 
     scope:true, 
     link: function (scope, element, attrs) { 
      var resource = MyResource; 
      resource.name = 'Foo'; 
     } 
    }; 
}); 
One23SRCApp.directive('directive2', ['MyResource', function(MyResource) { 
    return { 
     restrict: "A", 
     link: function (scope, element, attrs) { 
      var resource = MyResource; 
      console.log(resource.name); 
     } 
    }; 
}); 

由于共享资源,因此指令2将记录'Foo'。尽管确保您的指令以正确的顺序运行!

**

你也可以做一个双向的每个指令到父范围数据绑定(请参阅该Chandermani答案),但上面是让数据非常有用和强大的方式,你不需要广播或跟踪html中的事情。

编辑: 虽然上面是在控制器和路线之间共享信息时非常有用,请检查出stevuu答案。指令似乎更好(虽然我没有尝试过)。

19

AngularJS支持指令控制器,它们是在需要相同控制器的多个指令之间共享的控制器。这允许您在任何需要该控制器的指令中访问和修改tableConfig,而无需声明单独的服务或事件。有关更多信息,请参阅directives documentation中的“创建可沟通的指令”。

例如,这是如何工作的ngModelngForm

+0

不错,我错过了选项完全。 –

+1

在“控制器构造函数”中找不到任何内容。但是,也许这就是你正在谈论的“创建指令沟通”部分? –

+0

你说得对,文档已更改,我正在更新答案。谢谢! –

4

Chandermani样本正在工作。然而,这种方式你仍然必须在你的指令上指定属性,并且它不再被隔离。这是对范围的污染...

我的建议是通过使用控制器以这种方式传递它来分享您的独立范围。 你的房子,你的代码!在编码之前思考,但最重要的是......享受!

One23SRCApp.directive('directive1',function() { 
    return { 
     restrict: "A", 
     scope: true, 
     controller : function($scope){ 
       $scope.tableconfig= {}; 
       this.config = function(){ 
        return $scope.tableconfig; 
       } 
     }, 
     link: function (scope, element, attrs) { 
      scope.tableconfig.tablename= "table"; 
     } 
    } 
}); 


One23SRCApp.directive('directive2',function() { 
    return { 
      restrict: "A", 
      //^ -- Look for the controller on parent elements, not just on the local scope 
      //? -- Don't raise an error if the controller isn't found 
      require: "^directive1", 
      link: function (scope, element, attrs) { 
       var tablename = scope.config().tablename; 
      } 
    } 
}); 

使用

<!-- Notice, no need to share a scope as attribute --> 
<div directive1> 
    <div directive2> 
    </div> 
</div>