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