2012-08-01 14 views
19

これを適切に言い表せない場合は、事前にお詫びします。 ng-modelのテキストボックスにng-repeatがあり、テキストボックスの値を取得しようとすると、常にundefinedになります。私は、それが対応するテキストボックスに入力したものを表示するだけです。

$scopeに問題があるようですが、$scope.postTextをグローバルにするか、コントローラのルートレベルでどのようにしてアクセス可能にするのですか?

は、ここで明確に物事を助けるためにJSFiddleです:あなたのクリック式でhttp://jsfiddle.net/stevenng/9mx9B/14/

答えて

25

あなたがpostTextを参照して、savePost機能にアクセスすることができます。これがng-repeatでなければ、$scope.postTextには正常にアクセスできますが、ng-repeatは各項目に新しい範囲を作成します。

Hereは更新されたフィドルです。

@Gloopyは、すでに述べたように
<div ng-repeat="post in posts"> 
    <strong>{{post}}</strong> 
    <input type="text" ng-model="postText"> 
    <a href="#" ng-click="savePost(postText)">save post</a> 
</div> 

$scope.savePost = function(post){ 
    alert('post stuff in textbox: ' + post); 
} 
+0

どのようにあなたがこれを得るだろうにモデルアップ働くためにはじめての? http://jsfiddle.net/stevenng/VnQqH/5/ – Steve

+9

http://jsfiddle.net/VnQqH/6/実際の現在のスコープを参照するのに 'this'を使用してください –

+0

ありがとうRenanは多くを助けます。私は、この ''のような2つのオブジェクトを渡して動作させました。しかし、シンプルな「this」を使う方がはるかに優れています! – Steve

45

は、NG-繰り返しは、あなたのposts配列内の各アイテムのための新しい子のスコープを作成します。 posts配列の各項目はプリミティブ(文字列)であるため、ng-repeatは各子スコープにpostプロパティも作成し、それぞれに適切な値を割り当てます。 ng-repeatブロックの内部はng-model="postText"です。これにより、各子スコープにpostTextプロパティが作成されます。ここではすべてが(4つのスコープの2のために)のように見えるということです:

ng-repeat scopes

ときにユーザーがテキストの入力テキストボックスの1つに、適切な灰色のボックスには、テキストを格納します。たとえば、灰色の2番目のボックスは、ユーザーが「ハイテク」テキストボックスに入力するテキストを格納します。)親スコープは子スコープのpostTextプロパティを見ることができません。これは問題です。 Gloopyの答え@

  1. :(NGリピート子スコープがprototypically親スコープから継承するため、子スコープがアクセスできる)親スコープの関数を定義し、子スコープのプロパティを渡す3つの一般的な解決策があります。値(つまり、postTextの値)を親まで返します。
  2. posts配列にプリミティブの代わりにオブジェクトを使用します。例えば、各配列項目がオブジェクトである(プリミティブではない)ので、あなたのNG-反復ループにおけるその後 $scope.posts = [ {type: 'tech'}, {type: 'news'}, ...];


    <input type="text" ng-model="post.postText">
    を使用するが、それぞれの子スコープではなく、アレイposts内の適切なオブジェクトへの参照を取得しますコピー(値の)。したがって、post.postTextは親$ scopeプロパティpostsで作成されるため、親スコープに表示されます。 (したがって、この場合、子スコープはsavePost()を呼び出すだけです - 親スコープまでの値を渡す必要はありません)
    つまり、ユーザーが「this is tech related」と入力した場合親のposts配列が自動的に次のように更新されます。
    $scope.posts = [ {type: 'tech', postText: 'this is tech related'}, {type: 'news'}, ...];
    最後の注意:postTextプロパティは、ユーザーが何かを入力するまで投稿オブジェクトに追加されません。
  3. ng-model="$parent.someProperty"を使用して、フォーム要素を子スコープではなく親スコープのプロパティにバインドします。このソリューションはあなたのシナリオに実装するのが難しく、スコープ継承のHTML構造に依存するので、やや壊れやすい解決策です...しかし、私は完全性のために言及します。

(第4の解決はこれのような解決策1.が、変化しているGloopyの答え@上のコメントで@Renanから提示されました:。。thisではなく親までの値を渡すのに使用されるI」 $スコープで定義された関数は、$スコープにのみアクセスして変更する方がよいと思います。)

詳細については、こちらを参照してください。 Prototypalスコープの継承がAngularでどのように機能するかについての情報(さらに多くの画像)を参照してください。What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

+0

私は何も渡さずにsavePost()を呼び出すことができる2を見ていません。子オブジェクトまたはインデックスを渡さずに特定の子スコープをどのように参照しますか? –

+0

@Dean、良い点。あなたは 'posts'をループしてどのファイルが変更されたかを判断できます(たとえば、「保存」ボタンが1つだけ必要な場合)。あるいは、各投稿に対して「投稿を保存」リンクが必要な場合は、引数として 'post.type'を渡すことができます。 –

+0

ParentScopeがボックスに入力されたテキストを見ることができない部分について図を作成すると、ダイアグラムがさらに改善される可能性があります。ボックスに入力されたものが親に見えないことを示すために、赤い線または他の方法で描きます。 –

2

これは遅い回答かもしれません。このフィドルを参照してください。 http://jsfiddle.net/X5gd2/ テキストボックスにテキストを入力した後、リンクをクリックするとFirebugのコンソールを参照してください。アイデアは、ng-repeatの中で繰り返される各ビューのitemcontrollerを持つことです。

アイテムコントローラ:

function postItemController($scope){ 
    $scope.savePost = function(){ 
     console.log($scope.postText + " which belongs to " + $scope.post +" will be saved") 
    } 
} 
1

スプリット見出しと値

angular.module('MyApp',[]); 

function PostCtrl($scope) { 
    $scope.posts = [{heading:'tech',value:''}, {heading:'news',value:''},  {heading:'sports',value:''},{heading:'health',value:''}]; 

    $scope.savePost = function(post){ 
     alert('post stuff in textbox: ' + post); 
    } 
} 

下記のHTML ...

<div ng-app="MyApp"> 
    <div ng-controller="PostCtrl"> 
     <div ng-repeat="post in posts"> 
      <strong>{{post.heading}}</strong> 
      <input type="text" ng-model="post.value"> 
      <a href="#" ng-click="savePost(post.value)">save post</a> 
     </div> 
    </div> 
</div> 

Check out this Fiddle..

関連する問題