繁体   English   中英

如何在AngularJS指令中重新渲染模板?

[英]How to re-render a template in an AngularJS directive?

我创建了一个生成Twitter按钮的指令。 由于这些按钮上的范围变量可能会发生变化,因此我需要在按钮发生时重建它。 目前,我正在使用jQuery empty()链接元素并重建按钮。

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()

有没有办法让指令完全重新渲染模板?

这是一个可重用的指令,您可以使用该指令在发送事件时重建已转换的内容:

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);

        }
    };

});

这是一个jsFiddle演示如何工作: http//jsfiddle.net/robianmcd/ZQeU5/

注意每次单击“触发器重新链接”按钮时,输入框的内容如何重置。 这是因为每当触发事件时,都会删除输入框并将其添加到DOM。

您可以按原样使用此指令,也可以对其进行修改,使其由scope.$watch()触发scope.$watch()而不是事件。

一些建议:

  1. 使用指令模板并将变量绑定到范围而不是手动创建HTML。 在这种情况下,您无需重新渲染模板。 当范围属性更改时,Angular将自行更新它。

  2. 使用attrs。$ observe函数在属性值更改时运行一些代码

你尝试做什么跟随指令中的编译功能,它重新渲染html。 你试过吗?

这是一种hacky方式,但在指令上放置一个ng-if truthy变量,当你想渲染,设置和取消设置truthy变量时:

angularjs:强制重新渲染/完全刷新指令模板

另一种实现此目的的方法是使用ng-if。

例如: <myDirective ng-if="renderdirective"></myDirective>

renderdirective不为真之前,不会创建该指令。 如果您希望删除该指令并使用新的属性值重新创建它,那么这也将以相反的方式工作。

@rob回答的小变化:

import * as angular from 'angular';

class ReRenderDirective implements angular.IDirective {

  public restrict = 'A';
  public replace = false;
  public transclude = true;
  constructor( private $rootScope: angular.IRootScopeService, private $compile: angular.ICompileService ) {

  }

  public link = (
    scope: angular.IScope,
    element: angular.IAugmentedJQuery,
    attr: any,
    modelCtrl: any,
    transclude: angular.ITranscludeFunction ) => {

    let previousContent = null;

    let triggerRelink = () => {
      if ( previousContent ) {
        previousContent.remove();
        previousContent = null;
      }

      transclude(( clone ) => {
        element.append( clone );
        previousContent = clone;

        element.html( attr.compile );
        this.$compile( element.contents() )( scope );
      } );

    };

    triggerRelink();
    this.$rootScope.$on( attr.reRender, triggerRelink );

  }

}

export function reRenderFactory(): angular.IDirectiveFactory {

  var directive = ( $rootScope: angular.IRootScopeService, $compile: angular.ICompileService ) => new ReRenderDirective( $rootScope, $compile );
  directive.$inject = [ '$rootScope', '$compile' ];
  return directive;
}

用于:

<div re-render="responsive">
  <header-component/>
</div>

并将其与代码中某处的$ broadcast结合使用:

this.$rootScope.$broadcast( 'responsive' );

我做了什么,是听页面大小调整,然后将触发广播。 基于此,我能够将组件的模板从桌面更改为移动。 因为示例中的header-component被转换,所以它被重新渲染并重新编译。

这对我来说就像一个魅力。

感谢Rob让我走上正轨。

使用ng-bind =“value”而不是{{value}}为我刷新了我的指令模板缓存。

<myDirective><span ng-bind="searchResults.leads.results.length"></span></myDirective>

代替

<myDirective><span>{{searchResults.leads.results.length}}</span></myDirective>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM