[解決済み] 新たに追加された入力要素に注目
質問
新しいAngular 2のアプリに
input
ボックスのリストがあります。ユーザーがリターンキーを押したとき、私は新しい
input
ボックスを追加します。というか、(非同期に)モデル内の配列に新しいエントリーを追加し、それによってAngular 2が自動的に新しい
input
ボックスが自動的に生成されます。
どうすれば
input
が自動的に追加されるようにするにはどうしたらよいでしょうか?
EDIT 1:
あるいは、DOMを生成する原因となっているモデルオブジェクトへの参照を取得することができます。コンポーネントコードから、特定のモデルオブジェクトを表すDOM要素を検索する方法はありますか?
EDIT 2:
これは、これを動作させるための私のコードです。これがAngular 2の開発者にとって十分に不快なものであり、返信を促すものであることを願っています:-)
app.WordComponent = ng.core
.Component({
selector: 'word-editor',
template:'<input type="text" [value]="word.word" (input)="word.update($event.target.value)" (keydown)="keydown($event)"/>',
styles:[
''
],
properties:[
'list:list',
'word:word'
]
})
.Class({
constructor:[
function() {
}
],
keydown:function(e) {
if(e.which == 13) {
var ul = e.target.parentNode.parentNode.parentNode;
var childCount = ul.childNodes.length;
this.list.addWord("").then(function(word) {
var interval = setInterval(function() {
if(childCount < ul.childNodes.length) {
ul.lastChild.querySelector('input').focus();
clearInterval(interval);
}
}, 1);
});
}
}
});
どのように解決するのですか?
もし許されるなら、@Sasxaの回答の一部を取り出して、あなたが探しているものに近づけるように修正します。
いくつかの変更点
-
を使うことにします。
ngFor
を使うことで、自分でやる代わりにangular2が新しい入力を追加するようにします。主な目的は、angular2がそれを反復処理するようにするだけです。 -
の代わりに
ViewChild
を使うことにします。ViewChildren
を返すもので クエリリスト を持ちchanges
というプロパティがあります。このプロパティはObservableであり、変更後の要素を返します。
ES5ではデコレータがないため、このプロパティは
queries
プロパティを使って
ViewChildren
コンポーネント
Component({
selector: 'cmp',
template : `
<div>
// We use a variable so we can query the items with it
<input #input (keydown)="add($event)" *ngFor="#input of inputs">
</div>
`,
queries : {
vc : new ng.core.ViewChildren('input')
}
})
フォーカス を最後の要素に設定します。
ngAfterViewInit: function() {
this.vc.changes.subscribe(elements => {
elements.last.nativeElement.focus();
});
}
先ほど言ったように、ViewChildren は QueryList を返し、その中には
changes
プロパティを含むQueryListを返します。これをサブスクライブすると、変更されるたびに要素のリストが返されます。リスト
elements
には
last
プロパティがあり、この場合最後の要素を返すので、ここでは
nativeElement
を使い、最後に
focus()
input要素の追加
これは純粋に利便性のためで、入力配列には
ngFor
.
add: function(key) {
if(key.which == 13) {
// See plnkr for "this.inputs" usage
this.inputs.push(this.inputs.length+1);
}
}
を押しています。 ダミー を押し、再描画するようにします。
ES5を使った例。 http://plnkr.co/edit/DvtkfiTjmACVhn5tHGex
ES6/TSを使用した例. http://plnkr.co/edit/93TgbzfPCTxwvgQru2d0?p=preview
2016年03月29日更新
時間が経過し、物事が明確になり、学ぶべき/教えるべきベストプラクティスが常に存在します。私はいくつかの点を変更することで、この回答を簡素化しました。
-
を使用する代わりに
@ViewChildren
を使って購読する代わりに、新しい入力が作成されるたびに インスタンス化されるディレクティブを作りました。 -
を使っています。
Renderer
を使ってWebWorkerの安全性を高めています。オリジナルの回答はfocus()
に直接アクセスします。nativeElement
というのはお勧めしません。 -
今、私が聴いているのは
keydown.enter
を聞くようになり、キーダウンイベントが単純化されました。which
の値をチェックする必要がありません。
要点に コンポーネントは以下のようになります(簡略化、フルコードは以下のplnkrsにあります)。
@Component({
template: `<input (keydown.enter)="add()" *ngFor="#input of inputs">`,
})
add() {
this.inputs.push(this.inputs.length+1);
}
そして、ディレクティブは
@Directive({
selector : 'input'
})
class MyInput {
constructor(public renderer: Renderer, public elementRef: ElementRef) {}
ngOnInit() {
this.renderer.invokeElementMethod(
this.elementRef.nativeElement, 'focus', []);
}
}
見ての通り、私は
invokeElementMethod
を呼び出して、トリガーとして
focus
をトリガーします。
このバージョンは、オリジナルのものよりずっとクリーンで安全です。
plnkrs がベータ12に更新されました。
ES5を使った例: http://plnkr.co/edit/EpoJvff8KtwXRnXZJ4Rr
ES6/TSを使用した例. http://plnkr.co/edit/em18uMUxD84Z3CK53RRe
2018年最新情報
invokeElementMethod
は非推奨です。Rendererの代わりにRenderer2を使ってください。
要素にidをつけると selectRootElement :
this.renderer2.selectRootElement('#myInput').focus();
関連
-
[解決済み] ngModel' は 'input' の既知のプロパティではないため、バインドできません。
-
[解決済み] Angularで@Input()の値が変更されたときに検出する方法は?
-
[解決済み] Angular 2におけるEventEmitter.next()とEventEmitter.emit()の相違点
-
[解決済み] 継承と依存性注入
-
[解決済み] Angular CLIで特定のバージョンのAngularをインストールするには?
-
[解決済み] AngularでFormArrayからすべての項目を削除する
-
[解決済み] Reactive Forms - フィールドをタッチしたものとしてマークする
-
[解決済み] Angular : ルートへの手動リダイレクト
-
[解決済み] aria-valuenow' は 'div' の既知のプロパティではないため、バインドできません。
-
[解決済み] Angular2 ルーターがクエリ文字列を保持する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Angular 2で`DOM Element`を取得する方法は?[重複しています]
-
[解決済み] コンポーネントクラスからテンプレート参照変数にアクセスする
-
[解決済み] Angular Materialでのデフォルトのソート - ヘッダーのソート
-
[解決済み] angular-cliのビルドでカスタムファイルをインクルードするには?
-
[解決済み] .tsファイルはTypeScriptのコンパイルの一部ですが、使用されていませんという警告を消すには?
-
[解決済み] Error: モジュールによってインポートされた予期しない値 'undefined'。
-
[解決済み] プロパティ 'controls' がタイプ 'AbstractControl' に存在しない Angular 4 [duplicate] 。
-
[解決済み] 角度の2つのスイッチケース値
-
[解決済み] エラー TS1192: モジュール '" A.module"' はデフォルトのエクスポートがありません。
-
[解決済み] Angular2 - コンポーネントロード時にテキストボックスにフォーカスを当てる