17

我想$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属性。我无法在其他指令中访问此范围属性。

那么我怎样才能在另一个指令中访问一个指令的范围呢?

4

4 回答 4

22

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

例如,这就是如何ngModelngForm工作的。

于 2013-08-27T13:13:50.107 回答
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);
        }
    };
});

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

**

您还可以将每个指令的双向数据绑定到父范围(请参阅 Chandermani 答案),但上述方法是一种非常有用且强大的方法,可以在您需要的地方获取数据,而无需广播或跟踪正是 html 中的内容。

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

于 2013-08-27T13:09:52.547 回答
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={};

于 2013-08-27T13:09:44.997 回答
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>
于 2014-10-24T12:59:53.437 回答