ご質問への回答
標準のプロトタイプ継承規則が適用されるため、ディレクティブ内の配列への変更を元の配列に反映させることは機能するはずです。これを行うときのディレクティブの意味(新しいスコープを作成する場合でも):
current_element_list[0] = 'new value';
その変更は、コントローラーの$scope.project.elements
変数に反映される必要があります。
ディレクティブが新しい scopeを作成しない場合、ディレクティブscope
に渡される変数は、含まれているコントローラーの変数と同じである必要があります$scope
。つまり、そのスコープにあるものは何でも好きなように直接変更できるはずです。したがって、ディレクティブでこれを行う場合:
scope.project.elements = ['new value'];
その変更は、コントローラーの$scope.project.elements
変数にも反映される必要があります。
ディレクティブが分離スコープを作成する場合scope.$apply($(this).attr('sortable-model'))
、属性の評価値を取得するために使用しないでください。代わりに、次を使用します。
scope : {
current_element_list : '=sortableModel'
}
これにより、sortableModel の評価値への双方向データ バインディングが作成され、 を介してディレクティブにアクセスできるようになりますscope.current_element_list
。
コードの改善案
この行に関して:
var current_element_list = scope.$apply($(this).attr('sortable-model'));
単に配列を「フェッチ」したい場合は、 use を使用する必要は$apply
なく、代わりに を使用します$eval
。この$apply
関数は主に、AngularJS コンテキストに戻すために使用され、ダイジェスト ループをトリガーし、すべてのモデルのバランスが取れており、すべての変更が考慮されていることを確認します。$eval
($apply
関数が呼び出す)は、指定されたスコープで指定された式を単純に評価します。
また、ディレクティブを使用すると、jQuery を使用して属性の名前や値、さらには要素自体をフェッチする必要がなくなります。リンク関数には 4 つの引数が渡されます。そのうちの 1 つは、要素の属性と属性値を持つオブジェクトです。ディレクティブのコントローラーには、同じものを返す $attrs サービスを注入することもできます。(ディレクティブのドキュメントを読む)
上記のコードを次のように書き直します。
link : function(scope, element, attrs, controllers) {
// ...
var current_element_list = scope.$eval(attrs['sortable-model']);
// ...
}