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

时间:2021-02-16 12:10:26

I want to share the $scope between the following two directives:

我想分享以下两个指令之间的$ 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;
        }
    };
})

In the HTML, I have:

在HTML中,我有:

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

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

I have created the directive named "directive1" with isolated scope, assigning the name "table" to the scope.tablename property. I am not able access this scope property in the other directive.

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

So how can I access the scope of one directive in another?

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

4 个解决方案

#1


5  

You can do a $rootScope.$broadcast on items that you need to sync across directive.

您可以在需要跨指令同步的项目上执行$ rootScope。$ broadcast。

Or you can pass a object to your directive1 isolated scope, which would act as a communication mechanism. On this object if you change sub property like tablename, that would affect in the parent scope.

或者,您可以将对象传递给您的directive1隔离范围,该范围将充当通信机制。在此对象上,如果更改子属性(如tablename),则会影响父作用域。

Something like

就像是

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;
        }
    };
})

The HTML becomes

HTML变成了

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

Your controller should have this object defined

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

$scope.tableconfig={};

$ scope.tableconfig = {};

#2


19  

AngularJS supports directive controllers, which are controllers that are shared between multiple directives that require the same controller. This allows you to access and modify tableConfig in any directive that requires that controller, without having to declare a separate service or event. For more information, look at "Creating Directives that Communicate" in the directives documentation.

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

This is how ngModel and ngForm work, for example.

例如,这就是ngModel和ngForm的工作方式。

#3


16  

My suggestion would be to use a shared resource, e.g. a service. Services are singletons, meaning there is only ever one instance of each service, so you can use them to share data between directives, controllers, scopes and even when changing page through routing.

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

You would define the resource service like this:

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

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

You could then inject that service into your directives (and controllers if need be) and use it like this.

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

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);
        }
    };
});

Directive2 will log 'Foo' since the resource is shared. Although make sure your directives are run in the correct order!

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

**

**

You could also do a two way data-binding from each directive into the parent scope (see Chandermani answer for that), but the above is a very useful and powerful way to get data where you need it without having to broadcast or keep track of exactly where things are in the html.

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

Edit: While the above is very useful when sharing info between controllers and routes, check out stevuu answer. It seems better for directives (although I have not tried it).

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

#4


4  

The sample of Chandermani is working. However this way you still have to assign the attribute on your directive and its not isolated anymore. This is a pollution on the scope...

Chandermani的样本正在运作。但是,通过这种方式,您仍然需要在指令上分配属性,而不再将其隔离。这是对范围的污染......

My advice is to share your isolated scope by using the controller an passing it this way. Your house, your code! Think before you code but most of all... ENJOY!

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

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;
           }
    }
});

Usage

用法

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

#1


5  

You can do a $rootScope.$broadcast on items that you need to sync across directive.

您可以在需要跨指令同步的项目上执行$ rootScope。$ broadcast。

Or you can pass a object to your directive1 isolated scope, which would act as a communication mechanism. On this object if you change sub property like tablename, that would affect in the parent scope.

或者,您可以将对象传递给您的directive1隔离范围,该范围将充当通信机制。在此对象上,如果更改子属性(如tablename),则会影响父作用域。

Something like

就像是

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;
        }
    };
})

The HTML becomes

HTML变成了

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

Your controller should have this object defined

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

$scope.tableconfig={};

$ scope.tableconfig = {};

#2


19  

AngularJS supports directive controllers, which are controllers that are shared between multiple directives that require the same controller. This allows you to access and modify tableConfig in any directive that requires that controller, without having to declare a separate service or event. For more information, look at "Creating Directives that Communicate" in the directives documentation.

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

This is how ngModel and ngForm work, for example.

例如,这就是ngModel和ngForm的工作方式。

#3


16  

My suggestion would be to use a shared resource, e.g. a service. Services are singletons, meaning there is only ever one instance of each service, so you can use them to share data between directives, controllers, scopes and even when changing page through routing.

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

You would define the resource service like this:

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

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

You could then inject that service into your directives (and controllers if need be) and use it like this.

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

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);
        }
    };
});

Directive2 will log 'Foo' since the resource is shared. Although make sure your directives are run in the correct order!

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

**

**

You could also do a two way data-binding from each directive into the parent scope (see Chandermani answer for that), but the above is a very useful and powerful way to get data where you need it without having to broadcast or keep track of exactly where things are in the html.

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

Edit: While the above is very useful when sharing info between controllers and routes, check out stevuu answer. It seems better for directives (although I have not tried it).

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

#4


4  

The sample of Chandermani is working. However this way you still have to assign the attribute on your directive and its not isolated anymore. This is a pollution on the scope...

Chandermani的样本正在运作。但是,通过这种方式,您仍然需要在指令上分配属性,而不再将其隔离。这是对范围的污染......

My advice is to share your isolated scope by using the controller an passing it this way. Your house, your code! Think before you code but most of all... ENJOY!

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

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;
           }
    }
});

Usage

用法

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