web-dev-qa-db-ja.com

独自のテンプレートのないディレクティブの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

20
summer.is.gone

コードが現在機能している方法は、各ディレクティブの内容がディレクティブの分離されたスコープではなく親スコープにバインドされているため、各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を渡すことができます。

38
Michal Charemza

同じ混乱に直面してここに来ました。どうやら、ケースは次のとおりです。

トランスクルージョンはさておき、ディレクティブのテンプレート内の要素のみが、そのディレクティブによって作成された分離スコープにバインドされます。テンプレートを使用しない場合、ディレクティブが宣言されている要素のコンテンツは、分離されたスコープが存在しないかのようにバインドされます。

これは、これを示す上から変更されたプランカーです。 http://plnkr.co/edit/WqEKkNAj4p2Rly51LBzC?p=preview

10
Ivan Koshelev