Javascript 从模板多次调用函数

Javascript 从模板多次调用函数,javascript,angularjs,expression,angular-filters,Javascript,Angularjs,Expression,Angular Filters,在我的模板中,我有如下内容: {{formatMyDate(date)}} app.filter('formatMyDate', function () { return function (date) { if (!date) return ""; var result; //your code here return result; }; }); 但是date是一个范围变量,不能立即使用,因此此表达式

在我的模板中,我有如下内容:

{{formatMyDate(date)}}
app.filter('formatMyDate', function () {
    return function (date) {
        if (!date) return "";
        var result;
        //your code here    
        return result;
    };
});
但是
date
是一个范围变量,不能立即使用,因此此表达式将多次调用函数
formatMyDate()
(返回
undefined
),然后返回正确的值

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

有什么办法可以做到这一点? 一个定制的过滤器能帮我吗

编辑:
有人认为,这种行为可能是正常的,这取决于$digest周期。
然后我放置了一个
范围。$watch
来验证
日期的值更改了多少次。
请注意,我在指令中定义了这些

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')
}
检查我得到的控制台(伪代码)

我想知道这是否仍然是由于
$digest
周期造成的,或者是我的代码中的一个错误

您可以这样做:

{{date && formatMyDate(date)}}
仅当第一个条件存在且不同于null和undefined时,才会执行第二种情况


检查这把小提琴:

我建议你用不同的方式做事:

使用或如果您正在做一些非常独特的事情,并且日期
$filter
对您来说不够好,那么您可以创建自己的
$filter
,如下所示:

{{formatMyDate(date)}}
app.filter('formatMyDate', function () {
    return function (date) {
        if (!date) return "";
        var result;
        //your code here    
        return result;
    };
});
并在模板中这样使用它:

{{date | formatMyDate}}
更新: 我想我没有完全回答你的问题,我只是给了你关于如何改进代码的建议。这次我将尝试回答你的问题:

该循环是确保模型变化已解决的阶段, 以便可以使用更新的更改渲染视图。为了做到这一点,, Angular启动一个循环,在该循环中,每次迭代都计算所有模板表达式 以及
$scope
$watcher
功能。 如果在当前迭代中,结果与前一次相同, 然后,Angular将退出循环。否则,它将重试。 如果在10次尝试之后事情还没有解决,Angular将退出 有一个错误:错误

这就是为什么
$digest
循环第一次运行时,所有表达式都会(至少)计算两次。然后,每当您对
$scope
$scope
$watcher
之一进行更改时,
$digest
循环将再次运行,以确保事情已解决,因此表达式将再次计算。这就是Angular使“数据绑定”发生的方式,这是一种正常行为


所以在你的例子中,当你在模板中这样做:
{{formatMyDate(date)}
或者这个
{date | formatMyDate}}
你定义的角度表达式将在每次
$digest
循环运行时进行计算,你可以想象这是非常常见的。这就是为什么确保视图中使用的
$filters
(或函数)高效且无状态非常重要的原因

如果您使用的是角度>=1.3,那么一次性绑定可能适合您的需要。请检查。@NikosParaskevopoulos谢谢,但不是,我被迫使用1.0.8版。任何直接从表达式调用或通过ngRepeat/ngOptions(及类似)间接调用的函数都可能被多次调用。这就是角度的工作原理(参见)。也就是说,我认为在专用过滤器中添加额外的格式总是一个好主意。你查过了吗?@Yoshi我想这可能是问题所在。在这种情况下,过滤器也会被多次调用,或者angular足够聪明,不会这样做?是的,这可能是一个问题,这就是为什么手册中有多条关于保持观察者和过滤器简单的注释,以便多次调用不会有多大影响。重大操作应通过实际事件触发,例如ngChange/ngClick。AngularJs的较新版本试图通过一次性绑定(请参见Nikos注释)和其他优化来缓解此问题。@Leonardo yep,AngularJs中存在数据绑定,这意味着当模型更改时,视图会更新,因为您的“日期”是在$scope中定义的,$diggest循环将检测到更改并更新视图。@Leonardo有点像。。。通过创建自定义的$filter,您可以使代码更易于重用、测试和维护。因为formatMyDate函数是在哪里定义的?在那个控制器的$scope中,对吗?@Leonardo如果你非常关心函数调用,你应该使用
$scope.$watch
来检查
$scope.date
属性。@RahilWazir它也不会有帮助,在这种情况下,它将是多余的。@Leonardo在Yoshi伟大的解释之上,你可以看看我借的。另外,在这一节中,我简要解释了$diggest循环是如何工作的。我希望这有帮助。