2013-04-29 14 views
47

ここは私のplnkrです:http://plnkr.co/edit/n8cRXwIpHJw3jUpL8PX5?p=preview li要素をクリックするとフォームが表示されます。ランダムな文字列を入力し、 '通知を追加'を押します。テキストエリアテキストの代わりに、あなたは未定義になります。angularjsでテキストエリアの値を取得できません

マークアップ:

<ul> 
    <li ng-repeat="ticket in tickets" ng-click="select(ticket)"> 
     {{ ticket.text }} 
    </li> 
</ul> 
<div ui-if="selectedTicket != null"> 
    <form ng-submit="createNotice(selectedTicket)"> 
     <textarea ng-model="noticeText"></textarea> 
     <button type="submit">add notice</button> 
    </form> 
</div> 

JS一部: '未定義の'

$scope.createNotice = function(ticket){ 
    alert($scope.noticeText); 
} 

戻ります。私は、これが角度uiのui-ifを使用するときには機能しないことに気づいた。なぜこれがうまくいかないのでしょうか?それを修正するには?

答えて

86

あなたの問題はui-if部分にあります。代わりに、この問題が起こった

<textarea ng-model="noticeText"></textarea> 
58

<textarea ng-model="$parent.noticeText"></textarea> 

:あなたがこのような何かをしなければならない親スコープにアクセスするためになるような角度-UIがそのディレクティブ内で何のための新しいスコープを作成しているようですtextarea要素の周りの要素にng-ifディレクティブを使用しないで私に伝えてください。 Mathewの解は正しいが、その理由は別のものと思われる。この問題を検索すると、この投稿が表示されるので、私はこれを共有することに決めました。

あなたがここにAngularJSドキュメントhttps://docs.angularjs.org/api/ng/directive/textareaを見れば、あなたは角度が<textarea>「上書き」デフォルトのHTML textarea要素ということと呼ばれる独自のディレクティブを追加していることがわかります。これは、全体の混乱を引き起こす新しい範囲です。

あなたのコントローラで

$scope.myText = 'Dummy text'; 

のような変数があると

<textarea ng-model="myText"></textarea> 

AngularJSディレクティブのスコープでその変数を探します。このようなtextarea要素にそれをバインドする場合。そこにはないので、彼は$親に歩いて行く。変数はそこにあり、テキストはtextareaに挿入されます。 textareaのテキストを変更するとき、Angularは親変数を変更しません。代わりに、ディレクティブの有効範囲に新しい変数が作成され、元の変数は更新されません。 Mathewが示唆するようにtextareaを親の変数にバインドすると、Angularは常に正しい変数にバインドされ、問題はなくなります。

<textarea ng-model="$parent.myText"></textarea> 

希望これは、この質問に来て他の人のために物事をクリアして、と思うだろう「WTF、私はNG-場合は、私の場合は、他のディレクティブを使用していないのです!」使用構文コントローラとして

はずっと前にこれを追加したいが、それを行うための時間を見つけることができませんでした:

更新);私が最初にここに上陸したときのような私でした。これはコントローラを構築する現代的なスタイルであり、上記の$parentの代わりに使用する必要があります。どのくらいとの方法を見つけるために読んでください。

AngularJS以降1。2の場合、$scopeオブジェクトを使用する代わりに、コントローラオブジェクトを直接参照する機能があります。

<div ng-controller="MyController as myc"> [...] </div> 

人気のあるルーティングモジュール(UIルーター)は、その状態について同様のプロパティを提供します。 UIルータのあなたの状態の定義で次のコマンドを使用します。これは、ネストされたか、正しく対処スコープの問題を回避するために私たちを助け

[...] 
controller: "MyController", 
controllerAs: "myc", 
[...] 

。上記の例はこのように構成されます。最初にJavaScriptの部分。テキストを設定するために$scopeリファレンスを使用しないでください。thisを使用して、コントローラオブジェクトに直接プロパティをアタッチしてください。

angular.module('myApp').controller('MyController', function() { 
    this.myText = 'Dummy text'; 
}); 

コントローラとして構文は次のようになりますとtextareaためのマークアップ:

<textarea ng-model="myc.myText"></textarea> 

それは、ネストされたスコープの問題を解決ので、これは、この今日のようなものを行うための最も効率的な方法であります私たちは特定の地点で深い層数を数えます。 ng-controllerディレクティブを使用して要素内に複数のネストされたディレクティブを使用すると、古い方法の参照方法を使用しているときに、このようなものになる可能性があります。誰も本当に一日中それをやりたい!

<textarea ng-model="$parent.$parent.$parent.$parent.myText"></textarea> 
+2

グレート詳細な説明!非常に便利! – Wolfgang

+0

私の人生を保存しました。説明ありがとう! – NewestStackOverflowUser

2

実際問題はui-ifです。ディレクティブが式に基づいてdomツリーの一部を破棄して再作成する場合は、Angularです。これは、marandusが提案したように、textareaディレクティブではなく新しいスコープを作成することでした。

ここには、この井戸を説明するngIfとngShowの違いに関する記事が掲載されています。what is the difference between ng-if and ng-show/ng-hide

23

バインドスコープ変数への直接スコープ変数のプロパティではなく、テキストエリアへ:

コントローラ:

$scope.notice = {text: ""} 

テンプレート:

<textarea ng-model="notice.text"></textarea> 
+1

これは私にとってAngular 1.5で機能しました。奇妙な制限ですが、これはスコープ変数に直接バインドされた(1.3に戻っています)作業に使用されていたと確信しています... – robru

+1

このソリューションは '$ parent.notice'よりも優れています!! – Paritosh

+0

ソリューションが機能しました。直接結合が失敗した理由は何ですか? – Shivendra

関連する問題