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

时间:2013-08-27 12:46:30

标签: 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;
        }
    };
})

在HTML中,我有:

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

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

我创建了带有隔离范围的名为“directive1”的指令,将名称“table”分配给scope.tablename属性。我无法在另一个指令中访问此scope属性。

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

4 个答案:

答案 0 :(得分:20)

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

中的“创建通信指令”

这就是ngModelngForm的工作方式,例如。

答案 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>