如何在AngularJS中的两个指令之间共享范围?

Shi*_*mar 16 angularjs angularjs-scope

我想分享$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;
        }
    };
})
Run Code Online (Sandbox Code Playgroud)

在HTML中,我有:

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

<table directive1>
  <tr>
     <td>column1</td>
     <td>column1</td>
   </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

我创建了带有隔离范围的名为"directive1"的指令,为该scope.tablename属性指定了名称"table" .我无法在另一个指令中访问此scope属性.

那么如何在另一个指令中访问一个指令的范围呢?

Ste*_*ers 21

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

这是怎么ngModelngForm工作,例如.


Eri*_*onn 16

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

您可以像这样定义资源服务:

app.factory("MyResource",function(){
    return {};
});
Run Code Online (Sandbox Code Playgroud)

然后,您可以将该服务注入您的指令(如果需要,还有控制器),并像这样使用它.

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);
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

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

**

你也可以从每个指令到父作用域进行双向数据绑定(参见Chandermani的答案),但上面是一个非常有用和强大的方法,可以在不需要广播或跟踪的情况下获取所需的数据.确切地说html中的内容.

编辑: 虽然以上在控制器和路由之间共享信息时非常有用,但请查看stevuu答案.指令似乎更好(虽然我没有尝试过).


Cha*_*ani 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;
        }
    };
})
Run Code Online (Sandbox Code Playgroud)

HTML变成了

<table directive1 tableconfig='tableconfig'>
  <tr>
     <td>column1</td>
   <td>column1</td>
   </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

您的控制器应该定义此对象

$scope.tableconfig={};

  • 使用$ rootScope是一种反模式 (12认同)