从模板中多次调用的函数

时间:2014-10-22 13:27:07

标签: javascript angularjs expression angular-filters

在我的模板中,我有类似的东西:

{{formatMyDate(date)}}

但是date是一个不能立即使用的范围变量,因此在返回正确的值之前,此表达式将多次调用函数formatMyDate()(返回undefined)。

我可以检查函数中的date是否为空,但我想如果datenull,则根本不调用该函数会更干净。

有任何方法可以实现这一目标吗? 自定义过滤器会帮助我吗?

修改
有人建议这种行为可能是正常的,具体取决于$摘要周期 然后,我会使用scope.$watch来验证date值的变化次数。
请注意,我在指令中定义了这些。

scope.$watch('date', function(value){
  console.log('watched_date: ' + value)
})

我在我的formatMyDate函数中引入了console.log()

scope.formatMyDate = function(date){
  console.log("called_date: " + date)
  return dateService.format(date, 'YYYY-MM-DD')
}

检查我得到的控制台(伪代码)

called_date: undefined
watched_date: undefined
called_date: undefined // many many times (around 20/30)
called_date: correctValue //2 or 3 times 
watched_date: correctValue 
called_date: correctValue //other 3/4 times

我想知道这是否仍然归因于$digest周期,或者是我的代码中的错误

2 个答案:

答案 0 :(得分:7)

我建议你做不同的事情:

使用date $filter或者如果你做的事非常独特且日期$filter对你不够好,那么你可以创建自己的$filter,如下所示:< / p>

app.filter('formatMyDate', function () {
    return function (date) {
        if (!date) return "";
        var result;
        //your code here    
        return result;
    };
});

在模板中使用它:

{{date | formatMyDate}}

更新:

我想我没有完全回答你的问题,我只是就如何改进你的代码给了你建议。这次我会尝试回答你的问题:

$digest周期是Angular确保模型更改已经解决的阶段, 这样它就可以使用更新的更改呈现视图。为了做到这一点, Angular启动一个循环,其中每次迭代都会计算所有模板表达式 视图,以及$watcher的{​​{1}}函数。 如果在当前迭代中结果与前一个结果相同, 然后Angular将退出循环。否则,它会再试一次。 如果在10次尝试之后事情还没有解决,Angular将退出 错误:"Infite $digest Loop Error" (infdig)

这就是$scope周期第一次运行所有表达式的原因(至少)被评估两次。然后,每当您对$digest$scope的{​​{1}}之一进行更改时,$watcher周期将再次运行,以便确保事情已经解决,因此将再次评估您的表达式。这就是Angular如何使“数据绑定”发生,这是一种正常的行为。

因此,在您的情况下,当您在模板中执行此操作时:$scope或此$digest您定义的Angular表达式将在每次{{formatMyDate(date)}}周期运行时进行评估,你可以想象很多时候。这就是为什么确保您在视图中使用的{{date | formatMyDate}}(或函数)高效且无状态非常重要的原因。

答案 1 :(得分:1)

你可以这样做:

{{date && formatMyDate(date)}}

只会在第一个条件存在时执行第二种情况,并且与null和undefined不同。

检查这个小提琴:http://jsfiddle.net/HB7LU/7512/