Ng-клик не работает и #39; работает изнутри ng-репетировать. Снаружи работает. I' поставил [скрипку здесь][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>
[1]:
Как упоминала Вен, n-repeat
действительно создает дочерний scope для каждого элемента в цикле.
Дочерние области видимости имеют доступ к родительской области видимости's переменным и методам через наследование прототипа.
Путаница заключается в том, что когда вы делаете присваивание, он добавляет новую переменную в дочернюю область видимости, вместо того, чтобы обновлять свойство в родительской области видимости.
В ng-клике
, при вызове присваивания tiggerTitle =e.name
, она фактически добавляет новую переменную, называемую triggerTitle
, в дочернюю область видимости.
AngularJS docs хорошо объясняет это в разделе [Наследование JavaScript Prototypal Inheritance][1].
Как же обойти это и правильно установить переменную модели?
Быстрое и грязное решение - доступ к родительской области видимости с помощью $parent
подобным образом.
<a ng:click="$parent.triggerTitle=e.name; $parent.triggerEvent = e.action;">...
[Щелкните, чтобы увидеть рабочую версию скрипки с помощью решения $parent][2].
Использование $parent
может вызвать проблемы, если вы имеете дело с вложенными шаблонами или вложенными ng-повторами.
Лучшим решением может быть добавление функции в область видимости контроллера', которая возвращает ссылку на область видимости контроллера'.
Как уже упоминалось, дочерние области видимости имеют доступ для вызова родительских функций и, таким образом, могут ссылаться на область видимости контроллера'.
function MyCtrl($scope) {
$scope.getMyCtrlScope = function() {
return $scope;
}
...
<a ng-click="getMyCtrlScope().triggerTitle=e.name;getMyCtrlScope().triggerEvent = ...
[Щелкните, чтобы увидеть рабочую версию вашей скрипки с использованием лучшего метода] [3].
[1]: https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance [2]:
[3]: http://jsfiddle.net/xVZEX/27/Потому что повторение
создает новые возможности.
На этот вопрос неоднократно отвечали, потому что нюанс немного сложноват для понимания, особенно если вы не знаете и не знаете всего о js' о наследовании прототипа: https://github.com/angular/angular.js/wiki/Understanding-Scopes
ЭДИТ: похоже, что этот ответ очень спорный. Просто для ясности - так работает JS. Вы действительно должны' не пытайтесь выучить угловой, прежде чем понять, как 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!
Так, как мы можем обойти это?
Ну, мы можем "force" пройти через цепочку наследования - и, таким образом, мы'будем уверены, что мы'всегда получаем доступ к правильному объекту, будь то доступ к значению или его изменение.
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
.
Здесь мы можем использовать $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>
Угловой код 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'}]
}
вы можете протестировать его здесь
.Это работает
<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>
использовать это
<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-клик в ng:click и он начал работать, я еще не найти причину, просто быстро размещены, чтобы поделиться.
Я так долго путешествовал по интернету в поисках ответа на проблему ng-repeat, создавая в нем свой собственный масштаб. Когда вы изменяете переменную внутри ng-repeat, представления don't обновляются везде в документе.
И, наконец, решение, которое я нашел, было одним словом, и никто вам этого не скажет.
It's $parent. перед именем переменной и она изменит свое значение в глобальном масштабе.
Итак,
n-click="enterID=1"
becomes
ng-click="$parent.entryID=1"
Используйте контроллеры с 'as' ключевое слово.
Проверьте [документацию][1] по угловым разъемам на контроллерах.
Для вышеприведенного вопроса:
<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>
При этом свойства и функции будут прикреплены к области применения контроллера. [1]: https://docs.angularjs.org/api/ng/directive/ngController