在指令中使用链接函数可以附加不同的HTML元素

Use link function in directives to append different HTML elements

本文关键字:元素 HTML 指令 函数 链接      更新时间:2023-09-26

Fiddle

我有两个按钮。按下时会显示一个带有som文本的模态。但我也想根据按下的按钮动态添加一些html。

我已经尝试了$observe$watch方法,但在使其工作时遇到了问题。

这是我的密码。

angular.module('TM', [])
.controller('protocolCtrl', function(){
    this.text = 'Now looking at the protocol part';
    this.modalId = 'protocolModal';
})
.controller('categoryCtrl', function(){
    this.text = 'Now looking at the category part';
    this.modalId = "categoryModal";
})
.directive('modalDirective', function(){
    return {
        restrict: 'E',
        scope: {
            ctrl: '=',
            modalId: '@',
        },
        template:  ['<div id="{{modalId}}" class="modal fade" role="dialog">', 
                      '<div class="modal-dialog">',
                        '<div class="modal-content">',
                        '<div class="modal-header">',
                        '<h4 class="modal-title">Modal Header</h4>',
                        '</div>',
                        '<div class="modal-body">',
                        '<p> {{ ctrl.text }} </p>',
                        '</div>',
                        '<div class="modal-footer">',
                        '<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>',
                        '</div>',
                        '</div>', 
                        '</div>',
                        '</div>'].join(''),
        link: function(scope, element, attrs) {
            element.$observe('modalId', function(){
                var modal = element.find('#{{modalId}}');
                if(modal == 'protocolModal'){
                    element.find('#{{modalId}}').append('<div>this is a protocol test...</div>');
                } else {
                    element.find('#{{modalId}}').append('<div>this is a category test...</div>');
                }
            });
        }
    }
});

我不认为有element.$observe——有attrs.$observescope.$watch。作用域上已经有modelId,所以让我们使用它。

此外,注入一个元素作为模板的占位符,而不是id不稳定的.find,并相应地注入replaceWith

template: '<div id="{{modalId}}">'
             ...'
             <div class="modal-body">'
               <template-placeholder></template-placeholder>'
             </div>'
           </div>",
link: function(scope, element){
  // ...
  var unwatch = scope.$watch("modalId", function(val){
    var placeholder = element.find('template-placeholder');
    if(val == 'protocolModal'){
       placeholder.replaceWith('<div>this is a protocol test...</div>');
    } else {
      placeholder.replaceWith('<div>this is a category test...</div>');
    }
    unwatch(); // seems like you don't really need to set it again
  }
}

请参阅我更新了Fiddle

在链接函数中使用attr。因为您已经将属性赋予您的html,即:modalId="{{pctrl.modalId}}

 <modal-directive ctrl="pctrl" modal-id="{{pctrl.modalId}}"></modal-directive>


  if(attrs.modalId == 'protocolModal'){
     element.find('#{{modalId}}').append('<div>this is a protocol test...</div>');
  } else {
     element.find('#{{modalId}}').append('<div>this is a category test...</div>');
  }

编辑:

使用$timeout

$timeout(function () {
                if (attrs.modalId == 'protocolModal') {
                    element.find('#' + attrs.modalId).append('<div>this is a protocol test...</div>');
                } else {
                    element.find('#' + attrs.modalId).append('<div>this is a category test...</div>');
                }
            }, 1000)

现在为什么$timeout,因为您正在应用模板和计时您的链接函数附加您的div,这样它就不会应用您的div。因此,首先应用模板,然后在模板中附加您的div


如果您想在弹出内容中显示div,请使用此选择器。请参见此示例:https://jsfiddle.net/kevalbhatt18/o76hxj69/6/

element.find('#'+attrs.modalId +' .modal-body').append('<div>this is a protocol test...</div>');

如果您的两个DOM结构不同,您可以考虑根据某些参数值使用两个不同的模板。

templateUrl可以指定为一个函数,例如:

angular.module('Joy', [])
    .controller('ProfileCtrl', ['$scope', function ($scope) {
    $scope.user = {
        name: 'Elit'
    };
}])
    .directive('profile', [function () {
    return {
        restrict: 'A',
        templateUrl: function (elem, attrs) {
            return 'style-' + attrs.color + '.html';
        }
    };
}]);

并将指令用作:

<div ng-app="Joy" id="play-ground" ng-controller="ProfileCtrl">
    <div profile color="red"></div>
    <div profile color="green"></div>
</div>

在这种情况下,如果colorred,则指令将从style-red.html加载模板。否则来自style-green.html

在您的情况下,您可能会在外部控制器中维护一个标志。单击任一按钮将更改此标志值并传递给指令。该指令将相应地加载不同的模板。