根据this,“currency”过滤器将amount
作为第一个参数,并给出以下语法:
{{ currency_expression | currency : amount : symbol}}
但在以下示例中,它从未将amount
作为参数传递:
<span id="currency-default">{{amount | currency}}</span>
我假设示例中的amount
引用了文档中编写的语法中的currency_expression
。他们可以用这种方式将它写在文档中:
{{ currency_expression | currency : symbol}}
另一个示例是filter
filter,其语法如下:
{{ filter_expression | filter : array : expression : comparator}}
但在以下示例中,它从未指定“源数组”参数:
<tr ng-repeat="friendObj in friends | filter:search:strict">
我假设示例中的friendObj in friends
引用filter_expression
而search
引用array
如果我们要遵循写入的语法文件。他们可以用这种方式将它写在文档中:
{{ filter_expression_that_returns_array | filter : expression : comparator}}
我不确定我是否遗漏了一些东西但是文档对我来说没有意义。
我的问题是,我是否应该忽略文档中第一个参数必须是输入的内容?
答案 0 :(得分:1)
对于它的价值(因为根据经验,我们已经知道它就是这样),源代码表明表达式只需要在|
之前。
使用 version 1.2.16 的来源,而不需要详细说明:
<强> ng/parse.js#L103 强>
// In the OPERATORS hash:
var OPERATORS = {
...
'|': function (self, locals, a, b) {
return b(self, locals)(self, locals, a(self, locals));
},
...
<强> ng/parse.js#L579 强>
// `Parser`'s `filter()` method:
Parser.prototype = {
...
filter: function() {
var token = this.expect();
var fn = this.$filter(token.text);
var argsFn = [];
while (true) {
if ((token = this.expect(':'))) {
argsFn.push(this.expression());
} else {
var fnInvoke = function(self, locals, input) {
var args = [input];
for (var i = 0; i < argsFn.length; i++) {
args.push(argsFn[i](self, locals));
}
return fn.apply(self, args);
};
return function() {
return fnInvoke;
};
}
}
},
...
那么,我们学到了什么?
if ((token = this.expect(':'))) {
argsFn.push(this.expression());
解析器将在过滤器之后获取所有标记(由:
分隔)并将它们放入数组(argsFn
)。
var args = [input];
for (var i = 0; i < argsFn.length; i++) {
args.push(argsFn[i](self, locals));
}
在&#34;运行时&#34; (当实际过滤是hapenning时)将创建一个新数组(args
),该数组将包含input
(但是什么是输入?后面的更多内容)和每个参数先前存储在argsFn
中的令牌。
return fn.apply(self, args);
此args
数组将是过滤函数的参数列表。
因此,args
包含input
以及filter_name
之后的代币(如expression | filter_name : param1 : param2
所示)。
如果我们可以说服自己input
确实是表达式(出现在|
的左侧),那么我们应该确信没有必要将表达式显示为第一个参数之后 filter_name
。
var fnInvoke = function(self, locals, input) {
...
return function() {
return fnInvoke;
};
filter()
返回一个匿名函数,该函数在执行时返回函数fnInvoke
input
是fnInvoke
执行时的第三个参数。
现在让我们回到|
运营商:
'|': function (self, locals, a, b) {
...
这将导致调用此匿名函数,其中a
和b
分别是左侧(expression
)和右侧(filter_name:param1:param2
) 。
<子>
(实际上a
和b
不是左侧和右侧,但它们是在执行时返回在给定上下文中评估左侧和右侧的结果的函数(即范围)。
子>
return b(self, locals)(self, locals, a(self, locals));
这告诉我们通过调用filter()
(b(self, locals)
)返回的匿名函数返回的函数将使用以下参数执行:
`self`, `locals`, `a(self, locals)`
这意味着神秘的input
参数(记住它是fnInvoke
的第3个参数?)是a(self, locals)
。
并且a(self, locals)
基本上是在当前范围的上下文中评估|
运算符的左侧参数的结果,例如将字符串('someExpression'
)计算为当前范围($scope.someExpression
)中属性值的结果。
我不知道你是否相信(我不认为我会这样)。
我从解释中留下了很多细节,但感兴趣的读者可以深入研究这个来源并说服自己:)
<子> 我觉得发布如此冗长的答案而且实用价值很小,我觉得有点不好。叹... 子>
答案 1 :(得分:-1)
就个人而言,如果有疑问,我会一直阅读源代码。
对于您的<span id="currency-default">{{amount | currency}}</span>
示例:
https://github.com/angular/angular.js/blob/master/src/ng/filter/filters.js#L50
currencyFilter.$inject = ['$locale'];
function currencyFilter($locale) {
var formats = $locale.NUMBER_FORMATS;
return function(amount, currencySymbol){
if (isUndefined(currencySymbol)) currencySymbol = formats.CURRENCY_SYM;
return formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, 2).
replace(/\u00A4/g, currencySymbol);
};
}
我认为amount
然后是currency
,所以输入必须是第一个参数。
<强>更新强>
HTML模板绑定上下文中filter
的来源。
https://github.com/angular/angular.js/blob/master/src/ng/filter/filter.js#L116
function filterFilter() {
return function(array, expression, comparator) {
if (!isArray(array)) return array;
首先if
检查array
,即输入,作为第一个参数。