2014-11-21 123 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