0

我一直在試圖創建一個指令,我可以任意添加到現有窗體(作爲屬性),這使得窗體在點擊附近的觸發鏈接時變成彈窗。我已經讓指令工作了一次,但是一旦我再次單擊該鏈接,底層數據不會改變,按鈕(例如'close')將停止工作。Bootstrap彈出窗口指令和Angularjs的嵌套元素

一個plunker可以在這裏找到:http://plnkr.co/edit/2Zyg1bLearELpofeoj2T?p=preview

重現步驟:1.單擊鏈接,2.更改文本(注意,鏈接文本改變爲好),3.單擊Close(確定不會做在當前正確的事情),4.再次點擊鏈接,5.嘗試改變文本/點擊關閉,但沒有任何作品...

我讀過一個問題是,在引導彈出分離/附加到DOM,但我不知道我怎麼能解決這個問題。我也想避免第三方庫(如angular-ui),因爲我想避免開銷。

任何幫助,非常感謝。

更新 感謝Vasaka的提示,我能夠進一步發展。這個問題稍微改變了,因爲嵌套的指令現在似乎沒有受益於$compile,即我不相信它附加到範圍。

要重現該行爲,請單擊日期(下面的plunker鏈接),單擊彈出窗口中的日期(日期應增加)並關閉彈出窗口。再次重複這些步驟,您會注意到遞增日期不再有效。我試圖添加$compile(element.contents())(scope)以嘗試編譯嵌套指令simple-date-picker,但這並未解決問題。

下面是更新plunker:http://plnkr.co/edit/2Zyg1bLearELpofeoj2T?p=preview

和更新的代碼:

<!DOCTYPE html> 
<html> 

    <head> 
    <link data-require="[email protected]*" data-semver="3.0.3" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" /> 
    <script data-require="[email protected]" data-semver="1.9.1" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
    <script data-require="[email protected]" data-semver="2.3.2" src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> 
    <script data-require="[email protected]" data-semver="1.2.5" src="http://code.angularjs.org/1.2.5/angular.js"></script> 

    <style> 
    body {margin-top:40px; margin-left:40px;} 
    </style> 
    <script> 
     var module = angular.module('module', []); 

     module.directive('simpleDatePicker', function($compile) { 
     return { 
      restrict: 'E', 
      scope: { 
      date: '=' 
      }, 
      replace: true, 
      template: '<div ng-click="date.setDate(date.getDate()+5)"> {{ date }} </div>', 
     } 
     }); 

     module.directive('myForm', function() { 
     return { 
      restrict: 'E', 
      scope: { 
      popover: '=?', 
      value: '=' 
      }, 
      transclude: true, 
      replace: true, 
      template: 
      '<div>' + 
       '<a href="" ng-transclude></a>' + 
       '<form ng-submit="submit($event)" ng-hide="popover && !formVisible" ng-attr-popover="{{ popover }}" class="form-inline">' + 
       '<simple-date-picker date="value"></simple-date-picker>' + 
       '<div ng-hide="!popover">' + 
        '<button type="submit" class="btn btn-primary">OK</button>' + 
        '<button type="button" class="btn" ng-click="formVisible=false">close</button>' + 
       '</div>' + 
       '<div class="editable-error help-block" ng-show="error">{{ error }}</div>' + 
       '</form>' + 
      '</div>', 
      controller: function($scope, $element, $attrs) { 
      $scope.formVisible = false; 
      $scope.submit = function(evt) { 
       $scope.formVisible = false; 
      } 
      } 
     }}); 

     module.directive('popover', function($compile) { 
     return { 
      restrict: 'A', 
      scope: false, 
      compile: function compile(tElement, tAttrs, transclude) { 
      return { 
       pre: function preLink(scope, iElement, iAttrs, controller) { 
       }, 
       post: function postLink(scope, iElement, iAttrs, controller) { 
       var attrs = iAttrs; 
       var element = iElement; 

       // We assume that the trigger (i.e. the element the popover will be 
       // positioned at is the previous child. 
       var trigger = element.prev(); 
       var popup = element; 

       // Connect scope to popover. 
       trigger.on('shown', function() { 
        var tip = trigger.data('popover').tip(); 
        $compile(tip)(scope); 
        scope.$digest(); 
       }); 

       trigger.popover({ 
        html: true, 
        content: function() { 
        scope.$apply(function() { 
         scope.formVisible = true; 
        }); 
        return popup; 
        }, 
        container: 'body' 
       }); 
       scope.$watch('formVisible', function(formVisible) { 
        if (!formVisible) { 
        trigger.popover('hide'); 
        } 
       }); 
       if (trigger.data('popover')) { 
        trigger.data('popover').tip().css('width', '500px'); 
       } 
       } 
      } 
      } 
     }; 
     }); 

     function MyCtrl($scope) { 
      $scope.value = new Date(0); 
     } 

     angular.element(document).ready(function() { 
     angular.bootstrap(document, ['module']); 
    }); 

     </script> 
    </head> 

    <body ng-controller="MyCtrl"> 
    <my-form popover="true" value="value"> 
    {{ value }} 
    </my-form> 
    </body> 

</html> 
+2

angular-ui已經有一個彈出窗口,看看這個,我不知道你的意思是開銷,但是這些組件是以角度本地寫入的。 –

+0

我想避免額外的庫(angular-ui),我稱之爲開銷。 – orange

+1

您可能想要查看[this](https://github.com/mgcrea/angular-strap/blob/1dd96b9532c15eb044541ecc87cfaa856c1b239a/src/directives/popover.js)彈出窗口實現。這裏的關鍵是通過覆蓋本機引導程序功能來編譯popover內容,以反映popover顯示的範圍。 – Vasaka

回答

1

我想我解決了這兩個問題。如果有人有興趣,我會很快總結我的發現:

1)根據瓦薩卡的建議,彈出的tip需要綁定到範圍($compile(tip)(scope))。

2)第二個問題是嵌套的指令沒有被(1)中的$compile()調用編譯。這是由於在simple-date-picker的(嵌套)指令定義對象中設置了replace: true。由於原始指令標籤最初被替換,因此後續的任何$compile運行都不會將簡單日期選擇器識別爲Angular指令。

最終plunker(僅差別是replace: false)。

相關問題