Angularjs 自定义过滤器和依赖注入
Posted
技术标签:
【中文标题】Angularjs 自定义过滤器和依赖注入【英文标题】:Angularjs custom filter and dependency injection 【发布时间】:2014-01-30 09:20:31 【问题描述】:我是 AngularJS 的新手,我经常看到这种语法:
function someFunc()
return function(input)
return 'hello' + input;
上面的函数是我经常看到的通用语法,但是这个自定义过滤器的例子是特定的问题:
angular.module('bookFilters', [])
.filter('newBookFilter', function()
return function(input)
return 'The Book: ' + input.name + 'is new !';
;
);
我知道用另一个函数包装函数给了我使用依赖注入的机会,这是我的问题:
过滤器是否获取包装函数返回的函数?那么它是否能够使用依赖注入将值注入函数? 理论上:
这段代码:
bookObj | newBookFilter
会变成:
bookObj | function(input)return 'The Book: ' + input.name + 'is new !';
最后, 将返回函数的最终值。
为什么我不能将input
注入到第一个函数中,例如:
angular.module('bookFilters', [])
.filter('newBookFilter', function(input)
return 'The Book: ' + input.name + 'is new !';
);
为什么依赖注入只对返回的函数起作用?
我知道我在这里真的很困惑,如果有人可以帮助我,我将非常感激,谢谢大家,祝你有美好的一天。
【问题讨论】:
我们使用相同的函数(.filter)和相同的参数=>应该只有一个实现。角度框架如何区分您的第一种情况和第二种情况? 如果有类似的东西,就会有 2 个不同的函数,类似于我们所拥有的.factory
和 .service
你能帮我理解为什么angularjs需要2个函数才能使用依赖注入吗?
不,不是 Angular js 需要 2 个函数。我的意思是如果有多种方式来声明一个服务(被注入到其他人),那么必须有不同的功能,每个实现一个。
【参考方案1】:
我就是这样做的。
myApp.filter("myCustomDateFormatter", ['MyFactoryWithCustomFunctions', function (InjectedCustomFunction)
return function (input)
return InjectedCustomFunction.GetDateFromDotNetJson(input);
]);
【讨论】:
【参考方案2】:我将 Angular 工厂、服务、过滤器、指令包装器视为创建具有 Angular 风格的 javascript 对象和函数的烤箱。因此,从 Vasiliy 的回答中借用相同的风格:
// Don't use this code in a real app. It's just to illustrate a point.
angular.module('App', [])
// The following oven makes an Angular flavored JavaScript function that
// formats a currency
.service('currencyBadFilterFn',
// We inject a built-in Angular filter, currencyFilter, into our oven
function(currencyFilter)
// oven produces a function that can be used in other places in Angular code
return function(number)
// produced function returns a currency-formatted number when used
return currencyFilter(number)
)
.controller('MainCtrl',
function($scope, currencyBadFilterFn)
$scope.amount = currencyBadFilterFn(10) // $10.00
)
如您所见,创建服务时使用了相同的模式。在这里,我们正在创建一个服务,它返回一个我们可以在代码的其他地方使用的函数。
第一个函数,烤箱函数,以及 .service
或 .factory
或 .filter
包装器,告诉 Angular 如何构建你的函数。第一个函数的返回值就是您将在代码中使用的值。
【讨论】:
据我所知,我只能对包装函数使用依赖注入,所有的想法就像工厂实例化多次使用的值? @uBlankText 是的!这些包装器返回的值是一个单例,可以在代码的其他地方使用。 所以使用 2 个函数的原因(除了单例优势之外)是 1(包装函数)将具有依赖关系,并且返回的函数将接收实际值,因为正如我在 Vasiliy 示例中注意到的那样不能使用包装函数内部传递的任何实际值,但只有返回的函数才能获取值。 另外我想问一下,函数里面的函数是闭包的吗? 让我们continue this discussion in chat【参考方案3】:答案与您的问题相反。 Angular 将 only 注入到工厂函数中,但 不 注入到结果函数中:
.filter('newBookFilter', function($log, ...) // <- factory function
return function(input, ...) // <- resulting function
;
)
工厂函数具有任意注入参数。结果函数具有固定参数。
第二个原因是您可以在工厂函数中进行一些初始化。例如,当您定义 new directive 时,这很有用。工厂还返回闭包,它可以从工厂函数中捕获变量和参数。请参见下面的示例。它使用依赖注入来获取日志对象。 Here 是完整的例子。
.filter('joinBy', function ($log) // <- injected here
return function (input, delimiter) // <- used here
var res = (input || []).join(delimiter || ',');
$log.info(res);
return res;
;
);
【讨论】:
嘿,vassiliy,谢谢你的回答,你能解释一下:“工厂函数有任意注入的参数。结果函数有固定的参数。”.... 我标记了哪个函数是工厂,哪个是结果(参见第一个代码块)。通过“任意注入参数”,我的意思是角度将在此函数内传递“必需”参数。 Angular 看到函数参数名称来理解函数想要“吃”作为参数。 通过“固定参数”我的意思是角度总是发送相同的参数集并且看不到参数名称。很好的例子是新指令定义中的“链接”函数。它总是有 4 个参数 (最后一个是可选的)。我不能 100% 确定过滤功能的结果。我会搜索文件。 Here 是结果函数的参数描述。 Here 是对初始问题“过滤器定义由一个工厂函数组成,该工厂函数用依赖项注释并负责创建过滤器函数”(过滤器函数未用依赖项注释) 如果你要缩小它,它不会起作用。缩小会吃掉 $log,然后 angular 将无法解决它。你知道如何像控制器等那样用字符串表示法来定义它吗?以上是关于Angularjs 自定义过滤器和依赖注入的主要内容,如果未能解决你的问题,请参考以下文章