angularjsで「その場で編集」ディレクティブを書きたいです。そのディレクティブを再利用できるようにしたいので、ディレクティブには次の要件があります。
- 任意の要素をデコレートできる属性である必要があります。これは理にかなっています (div,span,li)
- 編集ボタンをサポートする必要があります。これをクリックすると、表示されている要素のセットが入力フィールドに変更されます。通常、連絡先 (番号、名前) などの 1 つのオブジェクトのプロパティ
このフィドルhttp://jsfiddle.net/honzajde/ZgNbU/1/で見られるディレクティブで、スコープの可視性のトリッキーな動作を発見しました。
- ディレクティブでコメントアウト: template と scope -> contact.number と contact.name が表示されます
- ディレクティブでコメントアウト: scope -> contact.number のみ表示
- 何もコメントアウトしていない → 何も表示されない
=> 両方がコメントアウトされている場合、テンプレートをディレクティブに追加するだけで、テンプレートが使用されていなくても contact.number がレンダリングされます。
ゲームのルールは何ですか?
<div>
<div ng-controller="ContactsCtrl">
<h2>Contacts</h2>
<br />
<ul>
<li ng-repeat="contact in contacts">
<span edit-in-place="" ng-bind="contact.number"></span> |
<span edit-in-place="" >{{contact.name}}</span>
</li>
</ul>
<br />
<p>Here we repeat the contacts to ensure bindings work:</p>
<br />
<ul>
<li ng-repeat="contact in contacts">
{{contact.number}} | {{contact.name}}
</li>
</ul>
</div>
</div>
var app = angular.module( 'myApp', [] );
app.directive( 'editInPlace', function() {
return {
restrict: 'A',
//scope: { contact:"=" },
template: '<span ng-click="edit()" ng-bind="value"></span><input ng-model="value"></input>',
link: function ( $scope, element, attrs ) {
// Let's get a reference to the input element, as we'll want to reference it.
var inputElement = angular.element( element.children()[1] );
// This directive should have a set class so we can style it.
element.addClass( 'edit-in-place' );
// Initially, we're not editing.
$scope.editing = false;
// ng-click handler to activate edit-in-place
$scope.edit = function () {
$scope.editing = true;
// We control display through a class on the directive itself. See the CSS.
element.addClass( 'active' );
// And we must focus the element.
// `angular.element()` provides a chainable array, like jQuery so to access a native DOM function,
// we have to reference the first element in the array.
inputElement[0].focus();
};
// When we leave the input, we're done editing.
inputElement.prop( 'onblur', function() {
$scope.editing = false;
element.removeClass( 'active' );
});
}
};
});
app.controller('ContactsCtrl', function ( $scope ) {
$scope.contacts = [
{ number: '+25480989333', name: 'sharon'},
{ number: '+42079872232', name: 'steve'}
];
});