我想在没有自己的模板的情况下在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);
}
}
});
答案 0 :(得分:38)
您的代码现在的工作方式是,每个指令的内容都绑定到父作用域,而不是指令的隔离作用域,因此每个target
都是对同一个变量的引用。 / p>
您需要做的是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);
});
}
}
})
你可以see this in this Plunker。它没有做的一件事是$watch
'target'的内容,所以我怀疑它不会对指令中“target”属性的变化做出反应。这可能最好留给另一个问题。
编辑:transclude
的使用不正确/过于复杂。您可以将scope
作为第一个参数传递,以将克隆正确绑定到正确的范围。
答案 1 :(得分:10)
来到这里面对同样的困惑。显然,案件如下。
除了排除外,只有指令模板中的元素才会绑定到该指令创建的隔离范围。如果您不使用模板 - 声明该指令的元素的内容将绑定,就像隔离范围不存在一样。
这是一个从上面展示的改良型羽毛球。 http://plnkr.co/edit/WqEKkNAj4p2Rly51LBzC?p=preview