web-dev-qa-db-ja.com

ng-clickはng-repeat内では機能しません

Ng-clickはng-repeat内からは機能しません。外で動作します。私は ここにフィドル を入れました

<div ng-controller="MyCtrl">
 <a ng-click="triggerTitle='This works!'">test</a>
    <h5>Please select trigger event: [{{triggerEvent}}] {{triggerTitle}}</h5>
       <ul class="dropdown-menu">
         <li ng-repeat="e in events">
             <a ng-click="triggerTitle=e.name; triggerEvent = e.action;">{{e.action}} - {{e.name}}</a>
         </li>
       </ul>
</div>
27
Alexandru R

Venが述べたように、ng-repeatはループ内の各アイテムの子スコープを作成します。子スコープは、プロトタイプ継承を通じて親スコープの変数とメソッドにアクセスできます。混乱を招く部分は、割り当てを行うときに、親スコープのプロパティを更新するのではなく、子スコープに新しい変数を追加することです。 ng-clickでは、割り当て呼び出しtiggerTitle =e.nameを行うと、実際にtriggerTitleという新しい変数が子スコープに追加されます。 AngularJSドキュメントでは、これを JavaScript Prototypal Inheritance というセクションで詳しく説明しています。

では、どのようにしてこれを回避し、モデル変数を適切に設定しますか?

手っ取り早い解決策は、$parentを使用して親スコープにアクセスすることです。

<a ng:click="$parent.triggerTitle=e.name; $parent.triggerEvent = e.action;">...

クリックして、Fiddle $ parentソリューションを使用)の作業バージョンを表示します。

$parentを使用すると、ネストされたテンプレートまたはネストされたng-repeatを処理している場合に問題が発生する可能性があります。より良い解決策は、コントローラーのスコープへの参照を返すコントローラーのスコープに関数を追加することです。既に述べたように、子スコープは親関数を呼び出すためのアクセス権を持っているため、コントローラーのスコープを参照できます。

function MyCtrl($scope) {
    $scope.getMyCtrlScope = function() {
         return $scope;   
    }
 ...

<a ng-click="getMyCtrlScope().triggerTitle=e.name;getMyCtrlScope().triggerEvent = ...

クリックしてFiddleより良い方法を使用)の作業バージョンを表示します

52
James Lawruk

なぜならng-repeatは新しいスコープを作成します。

特にjsのプロトタイプ継承についてすべてを知らない場合、ニュアンスを理解するのが少し難しいため、これは何度も回答されています: https://github.com/angular/angular.js/wiki/理解範囲

編集:この答えは非常に物議を醸すようだ。明確にするために、これがJSの仕組みです。 JSがどのように機能するかを理解する前に、Angularを学ぶことを試みるべきではありません。しかし、リンクは見逃しているようです

したがって、この場合のJSの動作例は次のとおりです。

var a = {value: 5};
var b = Object.create(a); // create an object that has `a` as its prototype

// we can access `value` through JS' the prototype chain
alert(b.value); // prints 5
// however, we can't *change* that value, because assignment is always on the designated object
b.value = 10;
alert(b.value); // this will print 10...
alert(a.value); // ... but this will print 5!

それでは、どうすればそれを回避できますか?

さて、継承チェーンを通過するように「強制」することができます。したがって、値にアクセスするか変更するかに関係なく、常に正しいオブジェクトにアクセスしていることを確認できます。

var a = {obj: {value: 5}};
var b = Object.create(a); // create an object that has `a` as its prototype

// we can access `value` through JS' the prototype chain:
alert(b.obj.value); // prints 5
// and if we need to change it,
// we'll just go through the prototype chain again:
b.obj.value = 10;
// and actually refer to the same object!

alert(b.obj.value == a.obj.value); // this will print true
14
Ven

これの代わりに:

<li ng-repeat="e in events">
  <a ng-click="triggerTitle=e.name; triggerEvent = e.action;">{{e.action}} {{e.name}}</a>
</li>

これを行うだけです:

<li ng-repeat="e in events">
  <a ng-click="$parent.triggerTitle=e.name; $parent.triggerEvent = e.action;">{{e.action}} {{e.name}}</a>
</li>

ng-repeatは新しいスコープを作成します。$parentを使用して、ng-repeatブロック内から親スコープにアクセスできます。

6
Iain Collins

ここでは、ng-repeatの外部のコードにアクセスできるように、$ parentを使用できます。

HTMLコード

<div ng-controller="MyCtrl">
        <a ng-click="triggerTitle='This works!'">test</a>


        <h5>Please select trigger event: [{{triggerEvent}}] {{triggerTitle}}</h5>
<br /> <br />
          <ul class="dropdown-menu">
            <li ng-repeat="e in events">
                <a ng-click="$parent.triggerTitle=e.name; $parent.triggerEvent = e.action;">{{e.action}} - {{e.name}}</a>
            </li>
          </ul>

Angular Jsコード

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
$scope.triggerTitle = 'Select Event';
$scope.triggerEvent = 'x';
$scope.triggerPeriod = 'Select Period';
$scope.events =  [{action:'compare', name:'Makes a policy comparison'}, {action:'purchase', name:'Makes a purchase'},{action:'addToCart', name:'Added a product to the cart'}]

}

ここでテストできます http://jsfiddle.net/xVZEX/96/

3
Harpreet Singh

この作品

<body ng-app="demo" ng-controller="MainCtrl">
 <ul>
    <li ng-repeat="action in actions" ng-click="action.action()">{{action.name}}</li>
 </ul>

 <script>
  angular.module('demo', ['ngRoute']);

  var demo = angular.module('demo').controller('MainCtrl', function ($scope) {
  $scope.actions = [
    { action: function () {
        $scope.testabc();
      }, name: 'foo'
    },
    { action: function () {
        $scope.testxyz();
      }, name: 'bar'
    }
  ];

  $scope.testabc = function(){
    alert("ABC");
  };

  $scope.testxyz = function(){
    alert("XYZ");
  };

 });
</script>
</body>
1
Uday Gowda

Ng-repeatが独自のスコープを作成するという問題に対する答えを探して、インターネットを長い間探していました。 ng-repeat内の変数を変更すると、ビューはドキュメント内のどこでも更新されません。

そして最後に、私が見つけた解決策は1つのWordでした。

それは$ parentです。変数名の前に追加すると、グローバルスコープで値が変更されます。

そう

ng-click="entryID=1"
になる
ng-click="$parent.entryID=1"

0
Rohan Hussain

これを使って

<div ng:controller="MyCtrl">
 <a ng:click="triggerTitle='This works!'">test</a>
    <h5>Please select trigger event: [{{triggerEvent}}] {{triggerTitle}}</h5>
       <ul class="dropdown-menu">
         <li ng:repeat="e in events">
             <a ng:click="triggerTitle=e.name; triggerEvent = e.action;">{{e.action}} -     {{e.name}}</a>
         </li>
       </ul>
</div>

Ng-clickをng:clickに変換し、機能し始めました。理由はまだわかりませんが、すぐに共有に投稿しました。

0
Hitesh Joshi

「as」キーワードを使用してコントローラーを使用します。

コントローラ上のanglejsで documentation を確認してください。

上記の質問:

<div ng-controller="MyCtrl as myCntrl">
 <a ng-click="myCntrl.triggerTitle='This works!'">test</a>
    <h5>Please select trigger event: [{{myCntrl.triggerEvent}}] {{myCntrl.triggerTitle}}</h5>
       <ul class="dropdown-menu">
         <li ng-repeat="e in myCntrl.events">
             <a ng-click="myCntrl.triggerTitle=e.name; myCntrl.triggerEvent = e.action;">{{e.action}} - {{e.name}}</a>
         </li>
       </ul>
</div>

これにより、プロパティと関数がコントローラーのスコープにアタッチされます。

0
Gerrard8