2014-11-21 49 views
0

我想创建一个指令,如果我声明:

<input my-directive show-button-bar="true" ng-model="fooBar"\> 

这将创建下列HTML:

<div on-toggle="toggled(open)" is-open="dpModel.displayDatePicker" dropdown="" class="btn-group ng-scope"> 
    <input my-directive show-button-bar="true" ng-model="fooBar"\> 
    <ul ng-click="$event.stopPropagation()" class="dropdown-menu datepicker-popup dropdown-menu-right"> 
    <div ng-if="showButtonBar"> 
     <div role="group" class="btn-group pull-left"> 
     <button ng-click="setToday()" class="btn btn-xs btn-info" type="button">Today</button> 
     <button ng-click="clear()" class="btn btn-xs btn-danger" type="button">Clear</button> 
     </div> 
     <button ng-click="toggled(false)" class="btn btn-xs pull-right btn-success" type="button">Done</button> 
    </div> 
    </ul> 
</div> 

这里的代码片断我的指令,我试图做到这一点:

var dropdown = $compile(angular.element('<div class=\"btn-group\" dropdown is-open=\"dpModel.displayDatePicker\" on-toggle=\"toggled(open)\"/>'))(scope); 

var ulTemplate = '<ul id=\"list2\"ng-if=\"showButtonBar\" class=\"dropdown-menu datepicker-popup\" ng-class=\"direction === \'right\' ? \'dropdown-menu-right\':\'dropdown-menu-left\'\" role=\"menu\" ng-click=\"$event.stopPropagation()\">' + 
       '<li ng-if=\"dpModel.displayDatePicker\">' + 
       '<datepicker ng-model=\"dpModel.value\" show-weeks=\"false\"></datepicker>' + 
       '</li>' + 
       '<div ng-if=\"showButtonBar\">' + 
       '<div class=\"btn-group pull-left\" role=\"group\">' + 
       '<button type=\"button\" class=\"btn btn-xs btn-info\" ng-click=\"setToday()\">Today</button>' + 
       '<button type=\"button\" class=\"btn btn-xs btn-danger\" ng-click=\"clear()\">Clear</button>' + 
       '</div>' + 
       '<button type=\"button\" class=\"btn btn-xs pull-right btn-success\" ng-click=\"toggled(false)\">Done</button>' + 
       '</div>' + 
       '</ul>'; 
var ul = $compile(angular.element(ulTemplate))(scope); 
element.wrap(dropdown); 
ul.insertAfter(element); 

我遇到的问题是UL部分

var ul = $compile(angular.element(ulTemplate)(scope)) 

将与范围正确编译但皮部dropdown不能正常获取的范围。这怎么可能?我究竟做错了什么?

更新: 忘了还提到,我需要在输入字段上有一个ng模型。

回答

0

[编辑]

有在第一实施例的误差。它应该是$ attrs。$ attr [this.name]不是$ attrs [this.name]。 下面是使用模板返回功能清洁返回例如: http://jsfiddle.net/numtpyL7/2/

module.directive('myDirective', function() { 

    var wrapperTemplate = '\ 
<div>\ 
    <ul>\ 
     <li>Some Text</li>\ 
    </ul>\ 
</div>'; 

    return { 
     template: function($element, $attrs) { 
      var directiveTag = $attrs.$attr[this.name]; 
      var inputElem = $element.clone().removeAttr(directiveTag); 
      var replacementHtml = angular.element(wrapperTemplate); 
      replacementHtml.prepend(inputElem); 

      return replacementHtml[0].outerHTML; 
     }, 
     replace: true, 
     priority: 999999 
    }; 

}); 

[原创]

使用$编译高优先级的终端指令去这样的事情的方式。 高优先级和终端意味着它将首先在元素上运行,而低于它的任何内容都不会运行。然后在指令编译代码中,从元素中删除该指令,用新DOM包装它,并用它替换当前元素。

module.directive('myDirective', function ($compile) { 

    var wrapperTemplate = '\ 
    <div on-toggle="toggled(open)" is-open="dpModel.displayDatePicker" dropdown="" class="btn-group ng-scope">\ 
     <ul ng-click="$event.stopPropagation()" class="dropdown-menu datepicker-popup dropdown-menu-right">\ 
      <div ng-if="showButtonBar">\ 
       <div role="group" class="btn-group pull-left">\ 
        <button ng-click="setToday()" class="btn btn-xs btn-info" type="button">Today</button>\ 
        <button ng-click="clear()" class="btn btn-xs btn-danger" type="button">Clear</button>\ 
       </div>\ 
       <button ng-click="toggled(false)" class="btn btn-xs pull-right btn-success" type="button">Done</button>\ 
      </div>\ 
     </ul>\ 
    </div>'; 

    return { 
     terminal: true, 
     priority: 999999, 
     compile: function($element, $attrs) { 
      // Remove this directive from the new wrapped template so that it does not get run again. 
      var inputElement = $element.removeAttr($attrs.$attr[this.name]); 

      // Add the new template to the DOM and remove the DOM of the current directive 
      var replacementHtml = angular.element(wrapperTemplate).prepend(inputElement.clone()); 
      $element.after(replacementHtml); 
      $element.remove(); 

      var subLink = $compile(replacementHtml); 
      return { 
       pre: function(scope, element, attrs) { 
        subLink(scope); 
       }, 
       post: function(scope, element, attrs) { 
       } 
      } 
     } 
    }; 

}); 
+0

这看起来像我想要采取的方法。但是,当我由于某种原因运行该代码时,它会在前置inputElement时出现某种无限循环。它只是不断崩溃我的浏览器,但是当我删除“.prepend(inputElement.clone())”时,它会停止无限循环。不知道问题是什么。 – user1200387 2014-11-24 16:12:11

-1

发生这种情况是因为在.wrap()内部克隆了下拉元素。虽然它仍然受限于范围,但这对内部表达式和指令没有影响,必须重新编译。更简单的解决方案是创建一个包装<my-directive>,以便下拉成为此结构中最顶层的元素。可以使用transclude来插入input

<div my-directive><input show-button-bar="true"></div> 

//within directive 
return { 
    transclude: true, 
    template: '<div class="btn-group" dropdown is-open="dpModel.displayDatePicker" on-toggle="toggled(open)">' + 
       '<ng-transclude></ng-transclude>' + 
       '<ul ...></ul>' + // UL template goes here 
      '</div>', 
    link: function (scope, element) { 
    //... link function code 
    } 
} 

在这种情况下,你似乎不需要编译。

+0

由于缺乏对我输入的ng模型的访问权限,因此这似乎不适用于我。 – user1200387 2014-11-24 18:30:09

+0

嗯,ng-model应该可以通过指令访问吗? – mikere 2014-11-24 18:37:49