我的示例代码(在下面)提出了两个问题:
“renderthis”函数在加载页面时针对每个项目调用两次
主要问题 - 当单击按钮时,我假设在计算 doit() 表达式后,ng-click 在范围上调用 $apply,这导致每个项目的两个 DOM 元素被重新 -渲染..现在,我明白这里每个项目的范围都以某种方式绑定(bind)到父范围或通过一些奇怪的隔离或嵌入或诸如此类的东西与它相关联,这是我还没有掌握的..有没有办法让 ng -click only call $digest on the child scope of each item or something of this sort?
这是我的代码:
html:
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="item in items">
<div>
<span>{{item.title}}</span>
<span>{{renderthis()}}</span>
<span>{{item.number}}</span>
<button ng-click="doit()">CLIQUE!</button>
</div>
</li>
</ul>
</body>
JS:
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.doit = function(){
console.log('doing it for item with title --> ', this.item.title);
}
$scope.renderthis = function(){
console.log('rendering this for item with title -->', this.item.title);
return '|';
}
$scope.items = [{title: 'hello', number: 1}, {title: 'shalom', number: 42}];
});
或者看这个plnkr:
最佳答案
在与@Mark 就此进行了一些乒乓球之后(见下文),有人建议我将问题改写为此类内容:“我如何才能在 ng-repeat 范围内制作点击事件-渲染受影响的项目(即不运行 $apply)“ 正如 Mark 解释的那样,这是为了强调,使用“ng-click”本身不太可能解决问题,因为它会发出硬编码“$apply”,这会运行摘要循环等。(请参阅下文)
我将接受我自己的答案,其中包括我自己的 ng-click 版本,它使用 $digest 而不是 $apply,因此不会触发所有 ng-repeat'ed 项目的重新呈现。
这里是修改后的 ng-click 代码(xng-click):
var xngEventDirectives = {};
angular.forEach(
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup'.split(' '),
function(name) {
var directiveName = directiveNormalize('xng-' + name);
xngEventDirectives[directiveName] = ['$parse', function($parse) {
return function(scope, element, attr) {
var fn = $parse(attr[directiveName]);
element.bind(name.toLowerCase(), function(event) {
fn(scope, {$event:event});
scope.$digest();
});
};
}];
}
);
这是一个演示它的 plnkr:
关于javascript - 我怎样才能在 ng-repeat 中创建一个点击事件只重新渲染受影响的项目(即不运行 $apply)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14612871/