根据AngularJS属性的指令装饰服务 [英] Decorate Service in Directive based on Attributes in AngularJS

查看:127
本文介绍了根据AngularJS属性的指令装饰服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

披露:我是新来的角,所以如果我这样做,出现奇怪的或完全错误的东西,随时指出这一点。

Disclosure: I'm new to angular, so if I'm doing something that appears strange or just plain wrong, feel free to point that out.

我有一个指令 vpMap ,我想用这样的:

I have a directive vpMap that I want to use like this:

<div my-map with-tile-layers with-geolocator></div>

我有我想要有条件装修地图服务的基础上,指令以开头的属性与

I have a Map service that I want to decorate conditionally, based on the attributes of the directive that begin with with

这看起来是这样的:

angular.module('myApp.map',[])
   .service('Map',someServiceFunction)
   .directive('myMap',['Map','$provide',function(Map,$provide) {

      return {
        controller: function($scope,$element,$attrs) {

          angular.forEach($attrs,function(val,key) {
             if(key.match(/^with/)) {
               switch(key) {
                 case 'withTileLayers':
                 $provide.decorator(Map,someDecoratorFunction);
                 break;
               }
             }
          });

        }
      };

   }]);

这是在这一点上,我发现我无法访问$在我的指令提供服务,虽然我不知道为什么。根据该文件你可以注入任何东西到指令和,我以为$提供像$ HTTP

It's at this point that I discover I can't access the $provide service in my directive, although I'm not sure why. According to the documentation you can inject anything into directives and, I thought $provide was one of those global angular services like $http

这是不好的架构?什么规则我是不理解?

Is this bad architecture? What rules am I not understanding?

推荐答案

供应商是为了通过在配置阶段的 $注射器中。

Providers are meant to be used by the $injector in the configuration phase.

供应商指南

在配置阶段已经结束,与供应商互动
  不允许
并创建服务的过程开始。我们称之为
  应用程序生命周期的一部分运行阶段。

Once the configuration phase is over, interaction with providers is disallowed and the process of creating services starts. We call this part of the application life-cycle the run phase.

所以,你将不得不使用配置块用来装饰。

So you would have to use the config block for decorating.

要装饰一个服务的条件的,你可以使用装饰的功能,里面的一些predicate,沿着这(未测试)线的东西:

To decorate a service conditionally, you may use some predicate inside the decorator's function, something along the lines of this (not tested):

// define a predicate that checks if an object starts with a key 
function keyInObject(obj, key) {
    var propKeys = Object.keys(obj),
        index = propKeys && propKeys.length || 0;
    while (index--) {
        if (propKeys[index].indexOf(key) === 0) {
            return true;
        }
    }
    return false;
}

app.config(function($provide) {

    // uhmm, decorate
    $provide.decorator('Map', function($delegate) {
        var service = $delegate;

        // only extend the service if the predicate fulfills        
        keyInObject(service, 'with') && angular.extend(service, {
            // whatever, man
        });

        return $delegate;
    });
});

然而,即使这样也不能帮助我们的,因为我们需要得到在链接阶段的,其售后服务是非常被注射的键(和饰)。

However, even this won't help us, as we need to get the keys in the linking phase, which is well after the service have been injected (and decorated).

要确保你完全了解这里的装饰的意义;我们使用装饰永久性地改变对象(服务)结构。的装饰,是指对象的元数据,而不是其状态

To make sure you fully understand the meaning of decoration here; we use decoration to permanently alter the object (the service) structure. Decoration refers to the object's meta data, not its state.

鉴于上述情况,最好的选择是简单地创建一个服务的所有必需的功能,并完全放弃装饰。后来,虽然里面的链接则可以使用迭代来决定调用哪个方法,例如:

Given the above, the best choice would be to simply create a service with all the required functionality, and abandon decoration altogether. Later, while inside link you can use the iteration to decide which of the methods to call, e.g.:

// I took the liberty of switching the positions of key/val arguments
// for semantics sake...
angular.forEach($attrs, function(key, val) {
    if (val.match(/^with/)) {
        switch (val) {
            case 'withTileLayers':
                Map.useTileLayers(); // use specific API in the service
                break;
        }
    }
});

这篇关于根据AngularJS属性的指令装饰服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆