2013-03-13 6 views
33

ng-click<p>に接続してモデルを更新しようとしています。ng-repeat内でng-clickで呼び出される代入式の動作

Iはng-repeatの外部代入式と、又は内部ng-repeat範囲メソッドを呼び出すと問題がありません。ただし、ng-repeatの中に割り当てを使用すると、無視されるようです。 Firefoxのコンソールには何のメッセージも表示されませんが、イベントが発生しているかどうかを確認するためにブレークポイントを設定していません。あなたは(以前のバリアントのカップルと一緒に)好む場合

<!DOCTYPE html> 
<html> 
<head> 
    <title>Test of ng-click</title> 
    <script type='text/javascript' src='http://code.angularjs.org/1.1.1/angular.js'></script> 
    <script type='text/javascript'>//<![CDATA[ 

     function MyCtrl($scope) { 
      $scope.selected = ""; 
      $scope.defaultValue = "test"; 
      $scope.values = ["foo", "bar", "baz"]; 

      $scope.doSelect = function(val) { 
       $scope.selected = val; 
      } 
     } 
     //]]> 

    </script> 
</head> 

<body ng-app> 
    <div ng-controller='MyCtrl'> 
     <p>Selected = {{selected}}</p> 
     <hr/> 
     <p ng-click='selected = defaultValue'>Click me</p> 
     <hr/> 
     <p ng-repeat='value in values' ng-click='selected = value'>{{value}}</p> 
     <hr/> 
     <p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p> 
    </div> 
</body> 
</html> 

フィドルは、hereです。

答えて

78

ディレクティブngRepeatは、反復ごとに新しいスコープを作成するため、親スコープで変数を参照する必要があります。

使用$parent.selected = value、のように:

<p ng-repeat='value in values' ng-click='$parent.selected = value'>{{value}}</p> 

注:関数呼び出しは、原型の継承のために伝播します。

詳細はThe Nuances of Scope Prototypal Inheritanceです。

+2

D'oh!私はそれが何か簡単でなければならないことを知っていた。 – kdgregory

+4

+1。 $ parentは動作しますが、あなたのモデルにオブジェクトを使用することが推奨されます(詳細は私の答えを見てください)。 –

20

@Stewieが述べたように、$ parentはこの問題を解決する方法の1つです。ただし、推奨される(by the Angular team)解決策は、$ scopeにプリミティブプロパティを定義しないことです。むしろ、$ scopeはあなたのモデルを参照するべきです。同じ名前の親スコープのプロパティを隠す/隠す子スコープではプリミティブプロパティが作成されないため、参照を使用すると問題が回避され、$ parentをいつ使用するかを覚える必要はありません。

HTML:

<p>Selected = {{model.selected}}</p> 
<hr/> 
<p ng-click='model.selected = defaultValue'>Click me</p> 
<hr/> 
<p ng-repeat='value in values' ng-click='model.selected = value'>{{value}}</p> 
<hr/> 
<p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p> 

はJavaScript:

$scope.model = { selected: ""}; 
... 
$scope.doSelect = function (val) { 
    $scope.model.selected = val; 
} 

Fiddle

私は最近、@Stewieが言及したwikiページを更新して、このアプローチを常に推奨しました。

+0

+1同意する。 $ parentを使用すると、最終結果が同じであっても、常にハッキリしているように見えます。私はそれを使っていません。私は今日、あまりにも怠け者で、 '。また、wikiを更新するための+1。 – Stewie

+1

私は、特別な "モデル"オブジェクトをハックで作成することを検討していると言います。複雑なページでエラーが発生する可能性が高くなります(何もない場合はスペルミスから)。個人的には、関数をモデル更新(そして 'ng-show'の式など)に最適なソリューションと考えています。 – kdgregory

+0

@kdgregory "$スコープの目的は、モデルではなく、モデルを参照することです"(Markが述べたAngularチームビデオから)。モデルとして必要なJavaScriptオブジェクトを使用してスコープからリンクすることができます。 – antoine

関連する問題