我想在没有自己的模板的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
您的代码现在的工作方式是,每个指令的内容都绑定到父作用域,而不是指令的隔离范围,因此每个指令target都是对同一变量的引用。
target
您需要做的就是transclude指令的内容。通常的用法是,您希望内容位于指令的父范围内,而不在隔离范围内。但是,您希望内容在指令的隔离范围内。因此,您必须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’的内容,因此我怀疑它不会对指令上“ target”属性的更改做出反应。这可能最好留给另一个问题。
$watch
编辑:使用transclude不正确/过于复杂。您可以将scopein作为第一个参数传递,以将克隆正确绑定到正确的作用域。
scope