AngularJS:过滤器多次触发,值通常是未定义的

时间:2014-09-01 00:18:49

标签: javascript angularjs angularjs-filter

以下代码段:

<h1>
    {{pid.pname}}
    <span style="font-size: 0.75em; text-shadow: none;">({{pid.pos}})</span>
    <span style="font-size: 0.5em; text-shadow: none;"><a ng-href="#/team/{{pid.team | the_link}}/">{{pid.group}}</a></span>
</h1>

过滤the_link定义如此......

myApp.filter('the_link', function() {
    return function(longname) {
        alert(longname);
        var parts = longname.split(' ');
        return parts[parts.length - 1].toLowerCase();
    }
});

在加载页面时多次触发alert()调用 - 似乎每次解析{{...}}时(在代码段中有4次),并且除了一次{{1}之外,它是未定义的最终处理{1}}。此外,ngHref四次中的三次......

这是为什么?我想我误解了某种生命周期。任何明确的赞赏。

2 个答案:

答案 0 :(得分:1)

您的问题主要是过滤器中没有空检查。您的过滤器将在每个摘要周期中运行,可能会发生插值指令在摘要周期中刷新自身时您还没有pidpid.team的值。您可能正在尝试使用同步调用加载它(例如: - http,resource),因此,只要您的过滤器运行longname未定义,您的过滤器就会失败,您将看到错误$interpolate:interr被捕获在插值期间。要修复它,只需在过滤器中添加一个空检查: -

 return function(longname) {
       //You should always do a null check because data might not be available by the time the filter runs.

        if(!angular.isString(longname)) return;  //or just if(!longname) return;

        var parts = longname.split(' ') ;
        return (parts[parts.length - 1] || "").toLowerCase(); //Just to be safer
    }

<强> Plnkr

答案 1 :(得分:0)

主要原因可能是你没有为团队辩护。

我使用跟随控制器完成了相同的过滤器。

function MyCtrl($scope) {
$scope.pid={pname:'test', pos:'test pos',group:'f b c d',team:'A B C G T H J'};

}

请参阅演示app

此外,angularjs使用了“脏检查”。方法,因此需要调用所有过滤器以查看是否存在任何更改。在此之后,它检测到一个变量有变化,然后再次执行所有过滤器以检测是否有其他变化。检查此post