Как я могу поделиться областью между двумя директивами в AngularJS?
Я хочу поделиться $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" с изолированной областью, присвоив имя "таблице" свойству scope.tablename
. Я не могу получить доступ к этому свойству scope в другой директиве.
Итак, как я могу получить доступ к области одной директивы в другой?
Ответы
Ответ 1
Вы можете сделать $rootScope.$broadcast
для элементов, которые необходимо синхронизировать с директивой.
Или вы можете передать объект в свою выделенную область директивы1, которая будет действовать как механизм связи. На этом объекте, если вы измените свойство sub, например 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={};
Ответ 2
AngularJS поддерживает директивные контроллеры, которые являются контроллерами, которые совместно используются несколькими директивами, требующими одного и того же контроллера. Это позволяет вам получить доступ и изменить tableConfig
в любой директиве, требующей этого контроллера, без необходимости объявления отдельного сервиса или события. Для получения дополнительной информации см. "Создание директив, которые обмениваются" в директивы документации.
Вот как работают ngModel
и ngForm
.
Ответ 3
Мое предложение состояло в том, чтобы использовать общий ресурс, например. сервис. Службы - это однополые слова, а это значит, что каждый экземпляр каждой службы имеет только один экземпляр, поэтому вы можете использовать их для обмена данными между директивами, контроллерами, областями и даже при изменении страницы с помощью маршрутизации.
Вы должны определить ресурсную службу следующим образом:
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-код.
Edit:
Хотя вышеприведенное очень полезно при обмене информацией между контроллерами и маршрутами, проверьте ответ stevuu. Кажется, лучше для директив (хотя я не пробовал).
Ответ 4
Образец Чандермани работает. Однако таким образом вам все равно придется назначать атрибут вашей директивы и ее не изолировать больше. Это загрязнение области...
Мой совет - поделиться своей изолированной областью, используя контроллер, проходя мимо него таким образом.
Ваш дом, ваш код! Подумайте, прежде чем вводить код, но больше всего... 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;
}
}
});
Использование
<!-- Notice, no need to share a scope as attribute -->
<div directive1>
<div directive2>
</div>
</div>