Подтвердить что ты не робот

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>
4b9b3361

Ответ 1

Как упоминалось в Ven, ng-repeat создает дочернюю область для каждого элемента цикла. У дочерних областей есть доступ к переменным и методам родительской области с помощью прототипального наследования. Запутанная часть - это когда вы выполняете задание, она добавляет новую переменную в область дочерних элементов, а не обновляет свойство в родительской области. В ng-click, когда вы делаете вызов назначения tiggerTitle =e.name, он фактически добавляет новую переменную с именем triggerTitle в область дочерних элементов. Документы AngularJS объясняют это хорошо в разделе, который называется Прототипное наследование JavaScript.

Итак, как вам обойти это и правильно настроить модель?

Быстрое и грязное решение заключается в доступе к родительской области с помощью $parent.

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

Нажмите, чтобы увидеть рабочую версию вашего скрипта, используя $parent решение.

Использование $parent может вызвать проблемы, если вы имеете дело с вложенными шаблонами или вложенными ng-повторами. Лучшим решением может быть добавление функции в область контроллера, которая возвращает ссылку на область управления. Как уже упоминалось, дочерние области имеют доступ к вызовам родительских функций и, следовательно, могут ссылаться на область контроллера.

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

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

Нажмите, чтобы увидеть рабочую версию вашего скрипта, используя лучший метод

Ответ 2

Потому что ng-repeat создает новую область.

Это ответили много раз, потому что нюанс немного сложно понять, особенно если вы не знаете все о прототипном наследовании js: https://github.com/angular/angular.js/wiki/Understanding-Scopes

EDIT: кажется, этот ответ очень спорный. Чтобы быть понятным - так работает JS. Вы действительно не должны пытаться изучить Angular, прежде чем понимать, как работает JS. Однако ссылка, похоже, пропустит

Итак, вот пример того, как 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

Ответ 3

Вместо этого:

<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.

Ответ 4

Здесь мы можем использовать $parent, чтобы мы могли получить доступ к коду вне ng-repeat.

Код 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/

Ответ 5

Это работает

<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>

Ответ 6

используйте этот

<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: нажмите, и он начал работать, но я еще не нашел причину, просто быстро опубликовал ее.

Ответ 7

Используйте контроллеры с ключевым словом "как".

Проверьте документацию на angularjs на контроллерах.

Для вышеуказанного вопроса:

<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>

Это добавит свойства и функции в область действия контроллера.