Как я могу поделиться областью между двумя директивами в AngularJS? - программирование
Подтвердить что ты не робот

Как я могу поделиться областью между двумя директивами в 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 в другой директиве.

Итак, как я могу получить доступ к области одной директивы в другой?

4b9b3361

Ответ 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>