2013-08-27 69 views
16

我想分享以下兩個指令之間的$scope如何在AngularJS中的兩個指令之間共享範圍?

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> 

我已經創建了一個名爲「指令1」與隔離範圍的指令,分配名稱「表」到scope.tablename屬性。我無法在其他指令中訪問此範圍屬性。

那麼我怎樣才能訪問另一個指令的範圍?

+0

如何在HTML中被組織的指示? – Chandermani

+0

@chnadermani我已更新我的問題,我已對不同元素應用指令。 – Shivkumar

回答

5

對於需要跨指令同步的項目,您可以執行$rootScope.$broadcast

或者您可以將一個對象傳遞給您的指令1隔離範圍,該範圍將充當通信機制。如果您更改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={};

+12

使用$ rootScope是一種反模式 –

+0

這是一種不好的做法,如果您只希望在指令之間共享相同的作用域,則您的隔離作用域會受到污染。 –

+0

@Chandermani。我堅持有關這個問題非常糟糕。我是新的角可以看到這個鏈接http://stackoverflow.com/questions/43521905/set-one-showrangeselector-for-dyo-dygraph謝謝 –

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將記錄'Foo'。儘管確保您的指令以正確的順序運行!

**

你也可以做一個雙向的每個指令到父範圍數據綁定(請參閱該Chandermani答案),但上面是讓數據非常有用和強大的方式,你不需要廣播或跟蹤html中的事情。

編輯: 雖然上面是在控制器和路線之間共享信息時非常有用,請檢查出stevuu答案。指令似乎更好(雖然我沒有嘗試過)。

19

AngularJS支持指令控制器,它們是在需要相同控制器的多個指令之間共享的控制器。這允許您在任何需要該控制器的指令中訪問和修改tableConfig,而無需聲明單獨的服務或事件。有關更多信息,請參閱directives documentation中的「創建可溝通的指令」。

例如,這是如何工作的ngModelngForm

+0

不錯,我錯過了選項完全。 –

+1

在「控制器構造函數」中找不到任何內容。但是,也許這就是你正在談論的「創建指令溝通」部分? –

+0

你說得對,文檔已更改,我正在更新答案。謝謝! –

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>