Angular JS 可调整大小的 div 指令
Posted
技术标签:
【中文标题】Angular JS 可调整大小的 div 指令【英文标题】:Angular JS resizable div directive 【发布时间】:2013-08-21 22:04:11 【问题描述】:我的网站将有多个部分,我打算调整每个部分的大小。为此,我制作了一个“可调整大小”的指令,例如:
<div class="workspace" resize="full" ng-style="resizeStyle()">
<div class="leftcol" resize="left" ng-style="resizeStyle()">
使用如下所示的指令:
lwpApp.directive('resize', function ($window)
return
scope: ,
link: function (scope, element, attrs)
scope.getWinDim = function ()
return
'height': window.height(),
'width': window.width()
;
;
// Get window dimensions when they change and return new element dimensions
// based on attribute
scope.$watch(scope.getWinDim, function (newValue, oldValue)
scope.resizeStyle = function ()
switch (attrs.resize)
case 'full':
return
'height': newValue.height,
'width': (newValue.width - dashboardwidth)
;
case 'left':
return
'height': newValue.height,
'width': (newValue.width - dashboardwidth - rightcolwidth)
;
etc...
;
, true);
//apply size change on window resize
window.bind('resize', function ()
scope.$apply(scope.resizeStyle);
);
;
);
如您所见,这只在窗口调整大小时调整每个 div 的大小,并且每个指令都有一个隔离范围。这适用于它的构建目标,但最终我想通过一个可拖动的栏来调整 div 的子集。比如
div1 div2
----------------
| || |
| || |
| || |
| || |
----------------
draggable bar in middle
在可拖动条的移动(水平方向)上,我可能需要通过父控制器的范围访问 div1、div2 的宽度(?)。我的问题是:
这是在 Angular 中制作可调整大小的 div 的“正确”方法吗?特别是当一个 div 的大小影响另一个时?
我个人认为 (1) 的答案是“不,我没有正确执行它,因为当每个指令都有一个隔离范围时,我无法在指令之间进行通信。”如果这是真的,我该如何考虑 div 之间的窗口和可拖动大小调整?
【问题讨论】:
我没有明确的答案,但我会检查 BootstrapUI Accordion 或类似的东西,其中有一个使用其他指令的主指令并在它们之间“传达”适当的信息打开和关闭相应的部分。我相信您将使用指令定义对象的 require 属性,请参阅此处的长版本 docs.angularjs.org/guide/directive 谢谢!我认为您的要求可能是正确的。这将使我可以访问另一个控制器... 我一直在尝试这个。正如 jayflo 建议的那样,我尝试了 jQuery-Splitter,但我对此感到很苦恼,并且也得到了代码不受支持的印象。我再次尝试使用JQueryUI resizable,效果很好。下一步是与Angular集成,我将使用AngularJS-JQueryUI 【参考方案1】:这个问题很老,但对于任何正在寻找解决方案的人,我构建了一个简单的指令来处理这个问题,用于垂直和水平调整大小。
Take a look at the Plunker
angular.module('mc.resizer', []).directive('resizer', function($document)
return function($scope, $element, $attrs)
$element.on('mousedown', function(event)
event.preventDefault();
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
);
function mousemove(event)
if ($attrs.resizer == 'vertical')
// Handle vertical resizer
var x = event.pageX;
if ($attrs.resizerMax && x > $attrs.resizerMax)
x = parseInt($attrs.resizerMax);
$element.css(
left: x + 'px'
);
$($attrs.resizerLeft).css(
width: x + 'px'
);
$($attrs.resizerRight).css(
left: (x + parseInt($attrs.resizerWidth)) + 'px'
);
else
// Handle horizontal resizer
var y = window.innerHeight - event.pageY;
$element.css(
bottom: y + 'px'
);
$($attrs.resizerTop).css(
bottom: (y + parseInt($attrs.resizerHeight)) + 'px'
);
$($attrs.resizerBottom).css(
height: y + 'px'
);
function mouseup()
$document.unbind('mousemove', mousemove);
$document.unbind('mouseup', mouseup);
;
);
【讨论】:
有 Angular >= 2 的版本【参考方案2】:我知道我参加聚会有点晚了,但我发现了这一点,需要我自己的解决方案。如果您正在寻找一个适用于 flexbox 且不使用 jquery 的指令。我在这里扔了一个:
http://codepen.io/Reklino/full/raRaXq/
只需声明您希望元素调整大小的方向,以及您是否使用 flexbox(默认为 false)。
<section resizable r-directions="['right', 'bottom']" r-flex="true">
【讨论】:
非常有帮助!对于那些想要让它真正快速工作的人来说,这是一个超级简单的 plunker(使用 angular-resizable)。看看index.html
plnkr.co/edit/ww3axpDkBTJuGX1gfIlA?p=preview【参考方案3】:
为了我的项目的需要,我添加了对最小值的支持,以便面板可以保持一些宽度或高度 - (这里是要点) - Github
另外,我创建了Github repo,我在其中添加了对位于主页面轴右侧的面板的支持以及对最小/最大值的支持。它现在处于示例阶段,但我愿意将它变成一个完整的 Angular 指令
【讨论】:
处理最小值/最大值的百分比值可能是另一个很好的补充。 @Mutant 当然,我会调查一下,谢谢你的建议【参考方案4】:这并不能完全回答问题,但更改 scope: true
解决了隔离范围问题。特别是,在我的 html 中,我有:
<div ng-controller="WorkspaceCtrl">
<div class="workspace" resize="full" ng-style="resizeStyle()">
<div class="leftcol" resize="left" ng-style="resizeStyle()">
<ul class="filelist">
<li ng-repeat="file in files" id=file.id ng-bind=file.name></li>
</ul>
<div contenteditable="true" ng-model="content" resize="editor" ng-style="resizeStyle()">
Talk to me
</div>
</div>
</div>
并且ng-repeat="file in files"
仍然可以访问控制器 WorkspaceCtrl 中定义的数组$scope.files
。所以scope:
将指令的作用域与父控制器的作用域截断,而scope: true
只是为指令的每个实例创建一个新作用域,并且指令的每个实例及其子控制器保留对父范围。
我还没有实现调整这些 div 大小的可拖动栏,但是当我这样做时会报告。
【讨论】:
实施这个有什么好运气吗? 不,抱歉。在窗口调整大小时使 div 调整大小很简单。我已经被其他事情分心了,并且没有尝试让 div 本身可调整大小。但是,我确信这将通过使用位于 div 之间的可拖动“垫片”来完成。此外,请确保您没有隔离任何您希望以这种方式调整大小的指令的范围。 自从我昨天问这个问题以来,我找到了一个相当不错的解决方案。查看这个 jQuery Splitter 的分叉版本:github.com/e1ven/jQuery-Splitter。要让它与 jQuery 1.9+ 一起工作,您需要恢复 jQuery.browser(我使用 this code)。将其与链接功能挂钩,您应该一切顺利。以上是关于Angular JS 可调整大小的 div 指令的主要内容,如果未能解决你的问题,请参考以下文章
为啥手动调整 Visjs 时间线图的高度(可调整大小)不起作用?
如何创建多个受容器 div 约束的可调整大小的同级 div 元素