How do I share scope between two directives in AngularJS?

前端 未结 4 992
夕颜
夕颜 2020-12-05 08:18

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

One23SRCApp.directive(\'directive1\',function() {
    return {
        restrict         


        
相关标签:
4条回答
  • 2020-12-05 08:37

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

    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.

    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

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

    Your controller should have this object defined

    $scope.tableconfig={};

    0 讨论(0)
  • 2020-12-05 08:45

    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...

    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>
    
    0 讨论(0)
  • 2020-12-05 08:46

    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.

    This is how ngModel and ngForm work, for example.

    0 讨论(0)
  • 2020-12-05 09:02

    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!

    **

    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.

    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).

    0 讨论(0)
提交回复
热议问题