重命名使用$提供第三方角度指令 - 不工作 [英] Renaming 3rd party Angular Directive using $provide - not working

查看:224
本文介绍了重命名使用$提供第三方角度指令 - 不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用一个大型站点旁边很多我自己的指令的优秀UI角度引导。对于整洁的缘故,我找了重命名夫妇UIB指令的方式,而不触及其code和跨越几个SO问题来了,看起来像是一个很好的解决方案。麻烦的是,它不是为我工作。这里是我的code。

I've using the excellent Angular UI bootstrap in a large site alongside lots of my own directives. For the sake of neatness I looked for a way of renaming a couple of the uib directives without touching their code and came across a couple of SO questions and what looked like a great solution. The trouble is that it's not working for me. Here's my code.

angular.module('s4p').config(function($provide, $compileProvider){

    console.log("I am logged in the console");

    $provide.decorator('uibPaginationDirective', function($delegate){

        console.log("I am not logged");

        $compileProvider.directive('s4pPaging', function(){
           return $delegate[0];
        });

        return function() { return angular.noop };

    });
});

我把一对夫妇console.logs在那里看到它是如何越来越远,我可以看到,它甚至没有运行装饰。起初我以为这可能已经在uiPaginationDirective简单的拼写错误,但如果我改变甚至单个字符,然后我在控制台中获得大注射器错误。因此,它肯定发现原来的指令,但装修的功能没有运行。

I've put a couple of console.logs in there to see how far it's getting and I can see that it's not even running the decorator. At first I thought this might have been a simple spelling mistake in uiPaginationDirective but if I change even a single character then I get a big injector error in the console. So, it's definitely finding the original directive but the decorate function is not running.

我在做一些真正愚蠢的?

Am I doing something really stupid?

修改:只是为了澄清,我使用的NG-注释来简化依赖注入,因此没有数组在.config依赖()的

Edit: Just to clarify, I'm using ng-annotate to simplify dependency injection, hence no array of dependencies in the .config()

编辑2 :如果元素不在页面,哪知上使用的装饰不会运行。所以,如果你使用旧的元素,则装饰不运行,但如果你使用新的别名则什么也不会发生的。我开始认为,除非原来的指令用于装饰呼呼这个code,我发现可能从来没有工作过。

Edit 2: The decorator doesn't run if the element isn't used on the page, which I didn't realise. So, if you use the old element then the decorator does run, but if you use the new alias then nothing happens at all. I'm beginning to think that this code I found may never have worked unless the original directive is used to kick the decorator into gear.

修改3 :我添加了一个赏金这一点,因为这将是很好找到一个解决方案。即使没有人能解决的例子code必有重命名第三方指令,而不改变它的其他方式?我发现了一个名为它做到这一点,但我真的不希望使用更多的第三方code别名插件,我想明白了解决方案。

Edit 3: I've added a bounty to this because it would be nice to find a solution. Even if nobody can fix the example code there must be other ways of renaming a third party directive without changing it? I have found a plugin called "alias" which does this but I don't really want to use more 3rd party code and I want to understand the solution.

修改4 :我一直在玩的code这是我借来的,使这个你可以在下面看到plunkr - 的 http://plnkr.co/edit/3aDEed?p=$p$pview 我认为这只是工作,因为该演示使用原来指令在HTML随后改名指令。如果从HTML删除原始之一,然后他们都消失了。这个我想是因为该指令装饰只运行在第一次使用的指令。所以,我现在的任务就是要找到一种方式来获得装饰不使用原来的指令运行,或者寻找一种更好的方法来重命名第三方指令...

Edit 4: I have been playing with the code which I borrowed to make this which you can see in the following plunkr - http://plnkr.co/edit/3aDEed?p=preview I think it only works because the demo uses the original directive in the HTML followed by the renamed directive. If you remove the original one from the HTML then they both disappear. This I assume is because the directive decorator is only run the first time the directive is used. So, my quest is now to find a way to get the decorator to run without using the original directive, or to look for a better way to rename a 3rd party directive...

修改5 :我尝试别的东西,这似乎是别名插件似乎什么引擎盖下是做

Edit 5: I tried something else which seems to be what the alias plugin seems to be doing under the hood.

angular.module('s4p').directive('s4pPaging', function(){

    return {
        restrict: 'EA',
        replace: true,
        template: '<uib-pagination class="s4pPaging"></uib-pagination>'
    }

});

...但不幸的是我得到了下面的错误。

...but unfortunately I get the following error.

错误:[$编译:multidir]多个指令[s4pPaging(模块:
  S4P),uibPagination]要求的模板上:...

Error: [$compile:multidir] Multiple directives [s4pPaging (module: s4p), uibPagination] asking for template on:...

我不明白为什么他们都要求模板。我会假设S4P寻呼将获得与UIB-分页和全部复制到UIB-分页元素的属性所取代。显然,我不明白为什么一些简单的像不起作用。

I don't get why they are both asking for template. I would have assumed that the s4p-paging would get replaced with the uib-pagination and all of the attributes copied on to the uib-pagination element. Clearly I don't understand why something simple like that doesn't work.

推荐答案

根据我的另一个问题的老办法,你将需要使用的指令至少一个实例在页面上自认为是角DI工作方式。它懒惰地实例化,只有当它被用于第一次的任何工厂。

Based on my old solution for another question, you would need to use at least one instance of the directive on the page since that is the way angular DI works. It lazily instantiates any factory only when it is used for the first time.

我在我的评论提及早期可以通过获取指令工厂 $ injector.get('directiveNameDirective')

As i mention in my comment earlier you can get any directive configuration by getting the directive factory (directive name suffixed by the the word "Directive")$injector.get('directiveNameDirective').

下面是一个抽象为解决该问题(记住这将解决命名冲突问题,以及从原来的线程也这是更加模块化,易于设置与您的应用程序只有一个配置调用)。

Here is an abstraction for resolving the problem (remember this will resolve the naming conflict problem as well from the original thread also this is more modular and easy set up with just one config call in your app).

您可以从我的仓库进入模块

angular.module('renameDirectiveUtil', [])
.provider('renameDirective', ['$provide' , '$compileProvider' , function($provide, $compileProvider){
    var directiveSet;

    this.setConfig = function setConfig(config){
      directiveSet = config;

       angular.forEach(directiveSet, function iterator(targetDir, sourceDir){
          sourceDir +=  'Directive';
          //Set up decorators
          $provide.decorator(sourceDir, function decorate($delegate){

             //Used to register a directive. $delegate is the original directive definition.
             $compileProvider.directive(targetDir, function(){
                return $delegate[0];
             });

              //This will remove the original directive definition, if not just return the delegate as is.
              return function() { return angular.noop };
          });
      });
    };

    this.$get  = ['$injector', function renameDirectiveService($injector){
      return { 
        rename : function rename(){
          angular.forEach(directiveSet, function(_,dir){
             var sourceDir = dir + 'Directive';
            //Just return the original directive definition which will trigger the decorator and redefine itself while renaming the new one.
            $injector.get(sourceDir);
          });
        }
      }
    }];
}]).run(['renameDirective',function(renameDirective){
  renameDirective.rename();
}]);

所有你现在需要做的是,包括这是你的模块依赖关系。

All you would need to do now is to include this as dependency in your module.

 angular.module('plunker', ['renameDirectiveUtil']);

和通过提供一个配置对象,它的格式为它配置 {sourceDirectiveName:targetDirectiveName}

and configure it by providing a config object which is of the format {sourceDirectiveName : targetDirectiveName }.

app.config(['renameDirectiveProvider',function(renameDirectiveProvider){
  renameDirectiveProvider.setConfig({
    'property' : 'cmProperty'
  });
}]);

下面是一个 plunker

Here is a plunker

这篇关于重命名使用$提供第三方角度指令 - 不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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