I am currently experimenting with integrating the materialize library with Angular. I have created an attribute directive to initialize the dropdown menu on an element.
However, I encountered an issue where the directive throws an exception (check the dev tools) when the data-activates
attribute uses a double-curly-brace expression. Here is a reproduction of the problem along with a hardcoded working version for reference:
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>
The error is coming from jQuery (Sizzle specifically):
Error: Syntax error, unrecognized expression: #item_{{id}}
It seems like the dropdown is being activated too early. I have attempted to set a priority
for my directive to ensure it runs after the other attribute has been properly populated, but that did not resolve the issue. I also looked at this Github repo with angular-materialize features, but found no specific solution to this case.
Is there a good workaround for this? Or do I need to watch the $scope.id
variable before calling dropdown()
?