如何在控制器中将函数应用于AngularJS表达式?

8

简单的问题,我想在控制器作用域内应用一个函数到一个表达式中。

这是我的控制器内的HTML代码:

<p><span ng-if="paginaDetail.pubdate !== '' ">Vanaf {{paginaDetail.pubdate}}</span></p>

这是我的 JavaScript。
$scope.formatMysqlTimestampToHumanreadableDateTime = function(sDateTime){
    sDateTime = sDateTime.toString();
    var sHumanreadableDateTime = sDateTime.substring(8, 10) + "/" + sDateTime.substring(5, 7) + "/" + sDateTime.substring(0, 4);
    sHumanreadableDateTime += " " + sDateTime.substring(11, 13) + ":" + sDateTime.substring(14, 16);
    return sHumanreadableDateTime;
};

我想要做的是将 formatMysqlTimestampToHumanreadableDateTime 应用于 paginaDetail.pubdate ,就像这样:

<p><span ng-if="paginaDetail.pubdate !== '' ">Vanaf {{formatMysqlTimestampToHumanreadableDateTime(paginaDetail.pubdate)}}</span></p>

或者这个

<p><span ng-if="paginaDetail.pubdate !== '' ">Vanaf {{paginaDetail.pubdate|formatMysqlTimestampToHumanreadableDateTime}}</span></p>

但两种方法都不正确。

第一种方法可行,但在控制台中出现以下错误:

Error: [$interpolate:interr] http://errors.angularjs.org/1.2.16/$interpolate/interr?p0=Tot%20%7B%7BformatMysqlTimestampToHumanreadableDateTime(paginaDetail.endpubdate)%7D%7D&p1=TypeError%3A%20sDateTime%20is%20undefined t/<@http://mysite.local/js/libs/angular.min.js:6:443 g/r@http://mysite.local/js/libs/angular.min.js:78:354 Yd/this.$gethttp://mysite.local/js/libs/angular.min.js:106:161 Yd/this.$gethttp://mysite.local/js/libs/angular.min.js:109:285 f@http://mysite.local/js/libs/angular.min.js:71:234 F@http://mysite.local/js/libs/angular.min.js:75:408 ve/http://mysite.local/js/libs/angular.min.js:76:457

http://mysite.local/js/libs/angular.min.js 第89行

第二种方法根本不起作用。

您有什么建议吗?非常感谢。

3个回答

7
如果我可以提供一个替代控制器动作的选项......这似乎是使用过滤器的绝佳场景。
思路是在输入放入html时使用过滤器进行过滤,就像{{myDate|format}}一样。
过滤器定义如下:
myApp.filter('format', function () {
   return function (input) {
      //your date parser here
   };
});

或者您想用它做其他任何事情。这样,您就可以重复使用它,而不必将函数放在想要使用它的每个控制器中。

这是一个fiddle,您可以扩展它以让其运转起来。

编辑 更仔细地查看错误,我认为你实际的问题是.pubdate没有填充(TypeError:sDateTime未定义)。尝试在函数中设置断点或查看控制台的输出。


不幸的是,我无法在fiddle上轻松复制它。我只能告诉你,我注意到了这种行为,使用过滤器时一切正常,就像我的第一个解决方案一样,但仍然存在相同的错误。所以我在控制台记录了input,我注意到如果我将此函数应用于我的pubdate,该值将被记录四次,前两次该值为_undefined_,另外两次则是正确的值。我只是不明白为什么会被调用次...有什么线索吗?因为我可以像这样解决它if(typeof input === 'undefined'){return "";}但这并不是一个很聪明的解决方案... - axel
1
Angular会循环遍历控制器上的模型,以查看是否有任何更改。这就是双向绑定的工作原理。如果您通过AJAX或任何其他不初始化.pubdate值的方法加载它第一次加载,那么它将首先为空,然后填充。在任何情况下,它都将不止一次被调用。这称为$digest循环。我仍然建议使用过滤器...关于digest的一些信息:http://onehungrymind.com/notes-on-angularjs-scope-life-cycle/ - Jorg
它是通过ajax api进行管理的,你说得对,所以我认为这个检查if(typeof input === 'undefined'){return "";}可能没问题。顺便感谢你提供的链接! - axel
这实际上是有效的,而我的函数调用似乎并没有起作用,反而输出了函数调用的字符串...真的不知道为什么。 - Akaisteph7

4
这个问题已经有了正确的答案,但这可能有助于更好地理解它。对于问题“如何在Angular表达式内运行/应用函数”,我可以介绍一种方法:
将您的函数分配给$scope.something并运行它。 例如:
在控制器中编写以下JavaScript代码:
$scope.printMe= function(text){
   return text;
}

HTML(超文本标记语言):

<p>{{printMe("Hello!")}}</p>

您将在您的

标签内获得Hello!


3

事实上你的示例{{func(param)}}可以正常工作:http://jsfiddle.net/HB7LU/4418/。问题出在其他方面。请尝试创建一个演示你的问题的代码片段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接