我想在以下两个指令之间共享$scope
:
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>
我创建了带有隔离范围的名为“directive1”的指令,将名称“table”分配给scope.tablename
属性。我无法在另一个指令中访问此scope属性。
那么如何在另一个指令中访问一个指令的范围呢?
答案 0 :(得分:20)
AngularJS支持指令控制器,指令控制器是在需要相同控制器的多个指令之间共享的控制器。这允许您在任何需要该控制器的指令中访问和修改tableConfig
,而无需声明单独的服务或事件。有关更多信息,请参阅directives documentation。
这就是ngModel
和ngForm
的工作方式,例如。
答案 1 :(得分: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将记录&#39; Foo&#39;因为资源是共享的。尽管确保您的指令以正确的顺序运行!
**
你也可以从每个指令到父作用域进行双向数据绑定(参见Chandermani的答案),但是上面是一个非常有用和强大的方法来获取你需要的数据,而无需广播或跟踪html中确切的位置。
修改强> 虽然以上在控制器和路由之间共享信息时非常有用,但请查看stevuu的答案。对于指令似乎更好(虽然我没有尝试过)。
答案 2 :(得分:5)
您可以对需要在指令中同步的项目执行$rootScope.$broadcast
。
或者您可以将对象传递给您的directive1隔离范围,该范围将充当通信机制。在此对象上,如果更改像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={};
答案 3 :(得分: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>