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>
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 = ...
なぜなら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
これの代わりに:
<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
ブロック内から親スコープにアクセスできます。
ここでは、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/
この作品
<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>
Ng-repeatが独自のスコープを作成するという問題に対する答えを探して、インターネットを長い間探していました。 ng-repeat内の変数を変更すると、ビューはドキュメント内のどこでも更新されません。
そして最後に、私が見つけた解決策は1つのWordでした。
それは$ parentです。変数名の前に追加すると、グローバルスコープで値が変更されます。
そう
ng-click="entryID=1"
になるng-click="$parent.entryID=1"
これを使って
<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に変換し、機能し始めました。理由はまだわかりませんが、すぐに共有に投稿しました。
「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>
これにより、プロパティと関数がコントローラーのスコープにアタッチされます。