19

これを正しく表現していない場合は、事前にお詫び申し上げます。ng-model内にテキストボックスがありng-repeat、テキストボックスの値を取得しようとすると常にundefinedです。対応するテキストボックスに入力したものをすべて表示したいだけです。

の問題のようですが、グローバルまたはコントローラーのルートレベルでアクセスできるようにするには$scopeどうすればよいですか?$scope.postText

これが問題を解決するのに役立つJSFiddleです:http://jsfiddle.net/stevenng/9mx9B/14/

4

4 に答える 4

45

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

ng-repeatスコープ

ユーザーが入力テキストボックスの1つにテキストを入力すると、適切な灰色のボックスにテキストが保存されます。(たとえば、2番目(上から)の灰色のボックスは、ユーザーが「tech」テキストボックスに入力したテキストを格納します。)親スコープは子スコープのpostTextプロパティを見ることができません-これはあなたが抱えていた問題です。3つの一般的な解決策があります:

  1. @Gloopyの答え:親スコープで関数を定義し(ng-repeat子スコープは通常、親スコープから継承するため、子スコープがアクセスできます)、子スコープのプロパティ値(つまり、postTextの値)を親に渡します。
  2. posts配列でプリミティブの代わりにオブジェクトを使用します。たとえば、
    $scope.posts = [ {type: 'tech'}, {type: 'news'}, ...];
    ng-repeatループでは、次を使用します。
    <input type="text" ng-model="post.postText">
    各配列アイテムはオブジェクト(プリミティブではない)であるため、各子スコープは、posts(値の)コピーではなく、配列内の適切なオブジェクトへの参照を取得します。したがって、post.postText親の$ scopeプロパティpostsで作成されるため、親スコープに表示されます。(したがって、この場合、子スコープは単に呼び出しsavePost()ます。親スコープに値を渡す必要はありません。)
    つまり、ユーザーが最初のテキストボックスに「これは技術関連です」と入力した場合、親のposts配列は次のように自動的に更新されます。
    $scope.posts = [ {type: 'tech', postText: 'this is tech related'}, {type: 'news'}, ...];
    最後の注意:ユーザーが何かを入力するまで、postTextプロパティはpostsオブジェクトに追加されません。
  3. ng-model="$parent.someProperty"子スコープではなく、親スコープのプロパティにフォーム要素をバインドするために使用します。このソリューションは、シナリオに実装するのが難しく、スコープの継承をHTML構造に依存しているため、かなり脆弱なソリューションです...しかし、完全を期すために言及します。

(4番目の解決策は@Gloopyの回答に対するコメントで@Renanによって提示されました。これは解決策1に似ていますが、バリエーションがあります:this親に値を渡す代わりに使用されます。私はこのアプローチのファンではありませんどの$scopeがアクセスまたは変更されているかを判断するのが難しいためです。$scopeで定義された関数は、独自の$scopeにのみアクセスして変更する方がよいと思います。)

Angularでプロトタイプスコープの継承がどのように機能するかについての詳細(およびさらに多くの写真)については、AngularJSでのスコープのプロトタイプ/プロトタイプの継承のニュアンスは何ですか?を参照してください。

于 2013-01-05T22:46:13.863 に答える
25

クリック式では、を参照postTextして関数でアクセスできますsavePost。これがng-repeatにない場合は、シングル$scope.postTextに正常にアクセスできますが、ng-repeatは各アイテムの新しいスコープを作成します。

これが更新されたフィドルです

<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);
}
于 2012-08-01T05:42:29.813 に答える
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")
    }
}
于 2013-02-27T22:46:01.583 に答える
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>

このフィドルをチェックしてください。

于 2014-10-07T04:26:00.003 に答える