Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I want to create reusable directive in AngularJS without own template. I also want to have isolated scope for that directive. What is the best practices for my approach? Why my example doesn't work as I expect?

I expected that I could edit obj1 and obj2 from directives separately.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
196 views
Welcome To Ask or Share your Answers For Others

1 Answer

The way your code is working now, is that the contents of each directive is bound to the parent scope, and not the isolated scope of the directive, so each target is a reference to the same variable.

What you'll need to do is to transclude the contents of the directive. The usual use for this is that you want the contents to be in the parent scope of the directive, and not in the isolated scope. However, you want the content to be in the isolated scope of the directive. So you'll have to call the transclude function manually, and bind the contents to the isolated scope of the directive:

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

You can see this in this Plunker. One thing it doesn't do is $watch the contents of the 'target' so I suspect it won't react to changes in the "target" attribute on the directive. This might be best left to another question.

Edit: the use of transclude was incorrect / overcomplicated. You can pass the scope in as the first parameter to properly bind the clone to the correct scope.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...