在 data-activates 属性中创建与 {{expression}} 一起使用的自定义具体化指令

Creating a custom materialize directive that works with an {{expression}} in data-activates attribute

我正在尝试让实体化库与 Angular 一起工作。为此,我编写了一个属性指令,用于初始化元素上的下拉菜单。

但是,在 data-activates 属性使用双花括号表达式的情况下,指令会抛出异常(请参阅开发工具)。这是一个重现(还有一个硬编码的工作版本供参考):

angular.module('foo', [])
  .directive('materialKebab', function() {
    return {
      link: function(scope, element, attrs) {
        $(element).dropdown();
      }
    };
  })
  .controller('bar', function($scope) {
    $scope.id = "abc123";
  });
.dropdown-button { cursor: pointer; background: #ddd; padding: 10px; display: inline-block; font-weight: bold; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.js"></script>

<div ng-app="foo" ng-controller="bar">
  Doesn't work:
  <div class="dropdown-button" data-activates="item_{{id}}" material-kebab>⋮</div>
  <ul class="dropdown-content" id="item_{{id}}">
    <li>Action 1</li>
    <li>Action 2</li>
  </ul>
</div>
<hr>
<div>
  Hard coded one works:
  <div class="dropdown-button" data-activates="hardCodedId">⋮</div>
  <ul class="dropdown-content" id="hardCodedId">
    <li>Action 1</li>
    <li>Action 2</li>
  </ul>
</div>

例外来自jQuery(确切地说是滋滋声):

Error: Syntax error, unrecognized expression: #item_{{id}}

很明显下拉菜单激活得太早了?我试过了 for my directive to try and make it happen after the other attribute was properly populated, but that didn't seem to work. I've also checked this Github repo with angular-materialize features,不过好像也没有特别考虑这个case

有什么好的解决办法吗?或者我是否必须在调用 dropdown() 之前求助于观察 $scope.id 变量?

再搜索一下,我找到了答案。就这样发下去,对路过的人有没有帮助,也许其他人能想出更好的答案?

这个问题只是两个问题组合的重复:

  • How to set the id attribute of a HTML element dynamically with angular js?
  • Angular expression in (data-, red) attribute

所以,只需在 data-activatesid 上使用 ng-attr- 前缀就可以了:

angular.module('foo', [])
  .directive('materialKebab', function() {
    return {
      link: function(scope, element, attrs) {
        $(element).dropdown();
      }
    };
  })
  .controller('bar', function($scope) {
    $scope.id = "abc123";
  });
.dropdown-button { cursor: pointer; background: #ddd; padding: 10px; display: inline-block; font-weight: bold; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.js"></script>

<div ng-app="foo" ng-controller="bar">
  Now does work:
  <div class="dropdown-button" ng-attr-data-activates="item_{{id}}" material-kebab>⋮</div>
  <ul class="dropdown-content" ng-attr-id="item_{{id}}">
    <li>Action 1</li>
    <li>Action 2</li>
  </ul>
</div>