【问题标题】:Angularjs custom filter and dependency injectionAngularjs 自定义过滤器和依赖注入
【发布时间】: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 个函数。我的意思是如果有多种方式来声明一个服务(被注入到其他人),那么必须有不同的功能,每个实现一个。

标签: javascript angularjs code-injection


【解决方案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 示例中注意到的那样不能使用包装函数内部传递的任何实际值,但只有返回的函数才能获取值。
    • 另外我想问一下,函数里面的函数是闭包的吗?
    【解决方案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 将无法解决它。你知道如何像控制器等那样用字符串表示法来定义它吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 2017-05-04
    • 1970-01-01
    • 2015-04-02
    • 1970-01-01
    相关资源
    最近更新 更多