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 自定义过滤器和依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

angularjs广播需要注入吗

angularJS自定义过滤器

AngularJs学习笔记6——四大特性之依赖注入

《AngularJS高级程序设计》学习笔记

使用 TypeScript 和注入的 AngularJS 过滤器

如何使依赖注入适用于 NestJS 中的全局异常过滤器?