如何使用angularJS将可拖动指令应用于bootstrap模式?

Saj*_*ran 5 javascript html5 twitter-bootstrap angularjs

我在我的Angular应用程序中使用bootstrap模式,它工作正常.我需要使它可拖动和可调整大小,所以我已经定义了一个指令.现在的问题是它被应用于模态窗口内的内容,因此模态窗口变得透明.

如何在打开窗口时将可拖动指令分配给模态窗口?这是代码,

HTML:

<div ng-controller="CustomWidgetCtrl">
    <div class="box-header-btns pull-right" style="top:10px" >
        <a title="settings" ng-click="openSettings(widget)"><i class="glyphicon glyphicon-cog"></i></a>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)

App.js:

var routerApp = angular.module('DiginRt',  ['ui.bootstrap','ngRoute']);
routerApp.controller('CustomWidgetCtrl', ['$scope', '$modal',
  function($scope, $modal) {

    $scope.openSettings = function(widget) {
          $modal.open({
            scope: $scope,
            templateUrl: 'chart_settings.html',
            controller: 'chartSettingsCtrl',        
            resolve: {
              widget: function() {
                return widget;
              }
            }
          });
        };
    }
    ])
Run Code Online (Sandbox Code Playgroud)

图表设置是另一个HTML页面.这是我的Draggable指令.

更新:

我已经更新了这个问题 Plunker

问题: 在此输入图像描述

Nae*_*ikh 9

我找不到将指令添加到打开的模态的方法ui-bootstrap,因为它使用模态对话框包装模板.

所以我所做的是使用以下代码将拖动事件设置为模态对话框本身(而不是指令).

我知道将事件添加到指令中的另一个元素不是最好的做法,但在这样的情况下也不是坏习惯,在这种情况下你不能直接向元素设置指令.

这样做的原因是因为ui-bootstrap没有提供一种向modal-dialogon modal.open函数添加指令的方法

这是在指令开头放置的代码:

element= angular.element(document.getElementsByClassName("modal-dialog"));
Run Code Online (Sandbox Code Playgroud)

傻瓜


Ste*_*hen 5

我赞成@Naeem_Shaikh 的回答,这基本上是对标准角度指令的改进。

但是,我已经能够修复标准角度可拖动指令的另一个问题。

标准指令对整个对话框施加了可拖动性。一方面,这就是我们想要的。我们想拖动整个对话框。但这有一个不幸的副作用,即在对话框中的各种编辑字段中单击不起作用:默认行为被阻止!不知何故,按钮已在引导程序中编码以克服此问题,但不是文本编辑字段。我猜作者没有考虑我的用例。但是对话框不仅仅是按钮!

这很棘手,因为需要拖动的是整个对话框,但您只希望通过单击标题“热点”中的单击来启动拖动。换句话说,发起拖动的热点是被拖动区域的一个子集。

Naeem 的修复使我能够使其正常工作,以便只有在标题中单击才能启动拖动。没有他的修复,坐标转换变得混乱。

function clickedWithinHeader(event) {
    var target = event.currentTarget;
    var hotspot = null;
    var hotspots = target.getElementsByClassName("modal-header");
    if (hotspots.length > 0) {
        hotspot = hotspots.item(0);
    }
    if (hotspot !== null) {
        var eY = event.clientY;
        var tOT = target.offsetTop;
        var y = eY - tOT;
        var hH = hotspot.offsetHeight;
        // since the header occupies the full width across the top
        // no need to check X.  Note that this assumes the header
        // is on the top, which should be a safe assumption
        var within = (y <= hH);
        return within;
    } else {
        return true;
    }
}


// Draggable directive from: http://docs.angularjs.org/guide/compiler
// Modified so that only clicks in the dialog header trigger drag behavior.
// Otherwise clicking on dialog widgets did not give them focus.
angular.module('drag', []).directive('draggable', function($document) {
"use strict";
return function(scope, element) {
    var startX = 0, startY = 0, x = 0, y = 0;
    element= angular.element(document.getElementsByClassName("modal-dialog"));
    element.css({
        position : 'fixed',
        cursor : 'move',
    });
    element.on('mousedown', function(event) {
//      // OK, where did they touch?  Only want to do this
//      // when they clicked on the header.
        if (!clickedWithinHeader(event)) {
            return;
        }
        // Prevent default dragging of selected content
        event.preventDefault();
        ...
Run Code Online (Sandbox Code Playgroud)

请注意,clickedWithinHeader() 逻辑仅适用于 Naeem 的改进。 可能有更好的方法来做到这一点,但这是有效的。只有在标题中的点击才会开始拖动,而其他地方的点击会做他们应该做的事情。

然而,这并不是全部答案,因为标准指令还在整个对话框上强加了移动光标,这非常令人不安,即使或特别是如果您无法拖动它出现的位置。

从指令中的 element.css 中删除它:

element.css({
    position : 'fixed',
});
Run Code Online (Sandbox Code Playgroud)

并使用 CSS 将移动光标仅绑定到模态标题

.modal-header 
{
    cursor: move;
}
Run Code Online (Sandbox Code Playgroud)

提供完整的解决方案。