独自のテンプレートを使用せずに、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);
}
}
});
コードが現在機能している方法は、各ディレクティブの内容がディレクティブの分離されたスコープではなく親スコープにバインドされているため、各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);
});
}
}
})
あなたは このプランカーでこれを見てください 。それがしないことの1つは$watch
'target 'の内容なので、ディレクティブの "target"属性の変更には反応しないと思います。これは別の質問に任せるのが最善かもしれません。
編集:transclude
の使用は正しくない/複雑すぎました。クローンを正しいスコープに適切にバインドするための最初のパラメーターとしてscope
を渡すことができます。
同じ混乱に直面してここに来ました。どうやら、ケースは次のとおりです。
トランスクルージョンはさておき、ディレクティブのテンプレート内の要素のみが、そのディレクティブによって作成された分離スコープにバインドされます。テンプレートを使用しない場合、ディレクティブが宣言されている要素のコンテンツは、分離されたスコープが存在しないかのようにバインドされます。
これは、これを示す上から変更されたプランカーです。 http://plnkr.co/edit/WqEKkNAj4p2Rly51LBzC?p=preview