如何重新编译使用“replace: true”的 Angular 1.x 指令

Posted

技术标签:

【中文标题】如何重新编译使用“replace: true”的 Angular 1.x 指令【英文标题】:How to recompile an Angular 1.x directive that uses "replace: true" 【发布时间】:2018-09-28 22:23:51 【问题描述】:

总结

我正在使用配置 replace: true 的第三方指令。

我想在用户每次单击按钮时重新编译指令。我已经尝试了几件事没有运气。例如,我尝试将 Cloudinary 指令包装在我自己的指令中,但我似乎无法得到它。任何帮助将不胜感激。

依赖关系

"angular": "1.6.2",
"cloudinary-core": "^2.5.0",
"cloudinary_ng": "^1.1.1",

控制器

$scope.rotate = (leader) => 
  leader.cloudinary_angle = 
    '0': '90',
    '90': '180',
    '180': '270',
    '270': '0'
  [leader.cloudinary_angle] || '0';
;

查看

<div ng-repeat="leader in leaders">
  <a href="#" ng-click="rotate(leader)">Rotate</a>
  <cloudimage leader="leader"></cloudimage>
</div>

没有用 #1

angular.module('app').directive('cloudimage', ($compile) => 
  return 
    restrict: 'E',
    replace: false,
    scope: 
      leader: '='
    ,
    link: (scope, element) => 

      let cloudinaryImage = $compile('<cl-image angle="' + scope.leader.cloudinary_angle + '"' +
                                              ' crop="fit"' +
                                              ' format="jpg"' +
                                              ' ' +
                                              ' public-id="' + scope.leader.cloudinary + '"' +
                                              ' quality="80"' +
                                              ' ' +
                                      '></cl-image>'
                            )(scope);

      element.html(cloudinaryImage[0]);

      scope.$watch('scope.leader.cloudinary_angle', (cloudinaryImage) => element.html(cloudinaryImage[0]));
    
  ;
);

没有用 #2

angular.module('app').directive('cloudimage', ($compile) => 
  return 
    restrict: 'E',
    replace: false,
    scope: 
      leader: '='
    ,
    template: '<cl-image crop="fit" format="jpg"  angle="angle" public-id="id" quality="80" ></cl-image>',
    link: (scope, element) => 
      scope.angle = scope.leader.cloudinary_angle || 0;
      scope.id = scope.leader.cloudinary;
    
  ;
);

没有用 #3

我可以装饰 3rd 方指令以使其成为 replace: false,但这会破坏它的嵌入。

angular.module('app').config(['$provide', function($provide) 
  $provide.decorator('clImageDirective', function($delegate) 
      var directive = $delegate[0];    
      directive.replace = false;
      return $delegate;
  )
]);

【问题讨论】:

cl-image 真的需要replace:真的吗?您可以扩展它并使其替换:false。 我也尝试过这种方法,但无法让它发挥作用。我想我可能知道为什么它不起作用。今晚回家后,我会尝试再次装饰指令,如果仍然无法获得它,则发布代码。 我可以装饰指令来制作replace: false,但是当我这样做时,cl-image 指令没有正确嵌入并且图像没有显示。 我明白了。您发布的代码不包含按钮。基本上,您需要在事件侦听器中执行 $compile()。 我从控制器和视图中添加了一些代码。希望它现在更有意义。当我单击“旋转”时,它会在视图中更新leader.cloudinary_angle。我在指令中对此进行了关注(请参阅“不起作用#1”)。我没有得到新的图像,而是在视图中得到&lt;cloudimage leader="leader" class="ng-isolate-scope"&gt;[object HTMLImageElement]&lt;/cloudimage&gt; 【参考方案1】:

#1 不起作用,因为html() 需要一个字符串,而不是 DOM 元素。 cloudinaryImage 元素不应转换为字符串,因为这会破坏有关元素的信息。

应该是:

scope.$watch('scope.leader.cloudinary_angle', (cloudinaryImage) =>  
  element.empty().append(cloudinaryImage)
);

【讨论】:

【参考方案2】:

是时候进行肮脏的黑客攻击了...您可以在具有单个元素的数组上使用 ng-repeat 重新编译任何内容(包括一次性绑定、任何指令):

  <body ng-controller="MainCtrl" ng-init="arr = []">
    <button ng-click="arr = []">Recompile</button>
    <p test ng-repeat="o in arr"></p>
  </body>

测试指令在哪里

app.directive('test', function() 
  return 
    replace: true,
    template: '<span>hello</span>',
    link: function() 
      console.log('I am linked');
    
  
)

附:你可以用 ng-if 做同样的事情,但是你需要 2 个摘要。 附言我同意这有点奇怪。

http://plnkr.co/edit/vlC7TV8eIrW1tLgcvP7Y?p=preview

【讨论】:

以上是关于如何重新编译使用“replace: true”的 Angular 1.x 指令的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 -fPIC 重新编译

如何使用 -fPIC 重新编译

如何使用带有 gprof 的 makefile 重新编译依赖项?

VUE 路由守卫 next() next({ ...to, replace true }) next(‘‘) 说明

如何重新编译linux内核

如何使用 -Xlint:unchecked 重新编译?