I've create a directive that generates Twitter buttons. Since the scope variables on those buttons may change, I need to rebuild the button when it happens. Currently, I'm using jQuery to empty()
the linked element and rebuild the button.
app.directive 'twitterShare', ($timeout, $window) -> restrict: 'E' template: '<a href="https://twitter.com/share" class="twitter-share-button" data-text="{{ text }}" data-url="{{ url }}">Twitter</a>' scope: text: '@' url: '@' link: (scope, el, attrs) -> scope.$watch 'text', -> rebuild() scope.$watch 'url' , -> rebuild() rebuild = -> $(".twitter-share-button").remove() tweet = $ '<a>' .attr 'href', 'https://twitter.com/share' .attr 'id', 'tweet' .attr 'class', 'twitter-share-button' .attr 'data-lang', 'en' .attr 'data-count', 'none' .text 'Tweet' el.prepend tweet tweet.attr 'data-text', scope.text tweet.attr 'data-url', scope.url $window.twttr.widgets.load()
Is there any way to get the directive to completely re-render the template instead?
For the record, to force angular to re-render the current page, you can use: $route. reload(); Causes $route service to reload the current route even if $location hasn't changed.
The very basic approach works by wrapping the element you want to rerender inside a ng-template element that gets rendered into a ng-container . On rerender you can just clear the content of the ng-container and create a new component from the ng-element .
templateUrl can also be a function which returns the URL of an HTML template to be loaded and used for the directive. AngularJS will call the templateUrl function with two parameters: the element that the directive was called on, and an attr object associated with that element.
Templates in AngularJS are simply an HTML file filled or enriched with AngularJS stuff like attributes and directives. A directive is a marker element that is used to target a particular attribute or class to render its behavior as according to the needs.
Here is a reusable directive you could use that will rebuild the transcluded content whenever an event is sent:
app.directive('relinkEvent', function($rootScope) { return { transclude: 'element', restrict: 'A', link: function(scope, element, attr, ctrl, transclude) { var previousContent = null; var triggerRelink = function() { if (previousContent) { previousContent.remove(); previousContent = null; } transclude(function (clone) { element.parent().append(clone); previousContent = clone; }); }; triggerRelink(); $rootScope.$on(attr.relinkEvent, triggerRelink); } }; });
Here is a jsFiddle demoing how it works: http://jsfiddle.net/robianmcd/ZQeU5/
Notice how the content of the input box gets reset every time you click the "Trigger Relink" button. This is because the input box is being remove and added to the DOM whenever the event is triggered.
You could use this directive as is or modify it so that it is triggered by scope.$watch()
instead of an event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With