如何从ng-repeat表达式中更新父范围变量?

时间:2014-03-22 17:11:03

标签: javascript angularjs angularjs-scope angularjs-ng-repeat ng-class

我遇到过必须从ng-repeat表达式更新范围变量的情况(实际上在ng-repeat中的ng-class调用)。

<div id="page" ng-controller="MainCtrl">
.
 <section id="body" ng-init="countMis = {num:0}">
.
<tbody>
  <tr ng-repeat="upperCaseLetter in alphabet.specialsUpper" ng-controller="letterController">
    <td>{{upperCaseLetter}}</td>
    <td>{{filteredLetter=(upperCaseLetter | lowercase)}}</td>
    <td>{{alphabet.specialsLower[$index]}}</td>
    <td><span ng-class="lowercaseEqual($index,filteredLetter)"></span></td>
  </tr>
</tbody>

并在app.js中:

function letterController($scope)
{
    $scope.lowercaseEqual = function(indx,letter)
    {       
        var returnStr="";

        if(letter == $scope.alphabet.specialsLower[indx])
        {
             returnStr = "glyphicon glyphicon-ok";
        }
        else
        {   
            $scope.countMis.num = $scope.countMis.num + 1;
            returnStr = "glyphicon glyphicon-remove";
        }

        return returnStr;
    };

}

Example App Screenshot

Ng-repeat位于子控制器中,我想要更新的数据位于其父控制器中。我知道您多次阅读同一个问题,请继续阅读并查看JsFiddle示例。

因此,表达式函数会检查特定ng-repeat迭代的过滤数据,如果它与其他对应的父作用域变量不匹配,则返回一个类,但它也应该更新父作用域计数器。 由于这些表达式不是仅评估一次,而是至少一次(因为对摘要进行脏检查),因此对于每种情况,结果计数器的递增次数不止一次。

我通过在ng-repeat之后计算应用于该特定数据的类来解决我的问题(您将在JsFiddle示例中看到)。 但是我想我将来会遇到同样的问题,所以我想学习如何在ng-repeat迭代的表达式中更新父范围。

我已经放了第二个JsFiddle,我尝试在父控制器和子设备上使用工厂,希望更新两个控制器的公共变量。当我记录(consol.log)每个迭代和工厂方法变量时,它显示迭代次数+ 1(仍为假值),但它没有反映在页面表达式上...根本没有意义

我很感激任何帮助。感谢。

JsFiddle 1 JsFiddle 2

1 个答案:

答案 0 :(得分:1)

由于观看的表达式(如ng-class指令隐含设置的表达式)“可以每 $digest() 执行多次,并且应该是幂等的”。 您应该了解 $watch() $digest() 功能的用途,并查找有关 Angular's digest cycle 的资源。

因此,在watchExpression中增加一个计数器并不是一个好主意 计数类似乎没问题。


顺便说一句,工厂方法将帮助您跨范围共享数据,但它无法帮助解决“每个摘要周期多次执行”问题。此外,在您的情况下,它可能是多余的,因为子范围和父范围可以直接共享数据 在任何情况下,要显示的结果,您必须将工厂的getMismatchCount()函数与您在HTML中使用的getMismatchCount()函数“绑定”在Mismatches Count from Factory: {{getMismatchCount()}}中):

function mainCtrl($scope, $window, repeatFactory)
    ...
    $scope.getMismatchCount = repeatFactory.getMismatchCount;