Подтвердить что ты не робот

Angularjs изолированная область для директив без собственного шаблона

Я хочу создать директиву многократного использования в AngularJS без собственного шаблона. Я также хочу иметь изолированную область действия для этой директивы. Каковы наилучшие методы моего подхода? Почему мой пример не работает, как я ожидаю?

Я ожидал, что я могу редактировать obj1 и obj2 из директив отдельно.

HTML:

<div ng-controller="MyCtrl">
  X1: {{ obj1.x }}, Y1: {{ obj1.y }}
  X2: {{ obj2.x }}, Y2: {{ obj2.y }}
  <hr>
  Edit obj1: 
  <div draggable target="obj1">
    <input type="text" ng-model="target.x">
    <input type="text" ng-model="target.y">
  </div>
  Edit obj2:
  <div draggable target="obj2">
    <input type="text" ng-model="target.x">
    <input type="text" ng-model="target.y">
  </div>
</div>

JS:

angular.module("App", [])
  .controller("MyCtrl", function($scope) {
    $scope.obj1 = {
      x: 10,
      y: 20
    };
    $scope.obj2 = {
      x: 30,
      y: 40
    };
  })
  .directive("draggable", function() {
    return {
      scope: {
        target: "="
      },
      link: function(scope, el, attrs) {
        console.log("scope: ", scope);
      }
    }
  });

PLUNKR: http://plnkr.co/edit/Dw8IiFVSOZGjSTFGRMzZ

4b9b3361

Ответ 1

Теперь, как работает ваш код, содержимое каждой директивы связано с родительской областью, а не с изолированной областью действия директивы, поэтому каждый target является ссылкой на ту же переменную.

Что вам нужно сделать, это transclude содержимое директивы. Обычное использование для этого состоит в том, что вы хотите, чтобы содержимое находилось в родительской области директивы, а не в изолированной области. Однако вы хотите, чтобы содержимое находилось в изолированной области действия директивы. Поэтому вам нужно будет вызвать функцию transclude вручную и привязать содержимое к изолированной области действия директивы:

.directive("draggable", function($compile) {
  return {
    transclude: true,
    scope: {
      target: "="
    },
    link: function(scope, element, attrs, ctrl, transclude) {
      transclude(scope, function(clone) {
       element.append(clone);
      });
    }
  }
})

Вы можете увидеть это в этом Plunker. Единственное, чего он не делает, это $watch содержимое "цели", поэтому я подозреваю, что он не будет реагировать на изменения атрибута "target" в директиве. Это может быть лучше всего оставить на другой вопрос.

Изменить: использование transclude было неправильным/сложным. Вы можете передать scope в качестве первого параметра, чтобы правильно привязать клон к правильной области.

Ответ 2

Приближалось к тому же путанице. По-видимому, дело в следующем.

Отключение в сторону, только элементы в шаблоне для директивы будут привязаны к изолированной области, созданной этой директивой. Если вы не используете шаблон - содержимое элемента, на котором объявлена ​​директива, будет связываться, как если бы изолированная область не была там.

Ниже представлен модифицированный плункер сверху, который демонстрирует это. http://plnkr.co/edit/WqEKkNAj4p2Rly51LBzC?p=preview