正确的方法 - Angular JS中的指令之间的通信

时间:2015-02-17 23:32:43

标签: javascript angularjs angularjs-directive

我想问一下在Angular应用程序中处理内部通信的最佳方法是什么。

示例如下:

我有一个全屏应用程序,具有响应式顶级菜单,全屏画布和控件,它们绝对位于画布的角落。画布应该几乎填满整个屏幕(顶部菜单的空格除外)。

要正确计算画布的高度,我需要知道顶部菜单的当前高度(其具有可变高度,例如基于视口宽度)。

我在canvas元素上有一个指令,它应该适当地调整画布大小。

但问题是让指令“知道”菜单高度的最佳方法是什么?

  • 我应该将额外参数传递给指令吗?
  • 我应该创建一个可以广播此信息的全球服务吗?
  • 我应该让父控制器来处理吗?
  • 或者我应该采用完全不同的方法?

Angular官方文档似乎对应用程序架构模式不是很有用。

谢谢。

更新 示例代码

HTML chunk

<div workspace-height>
    <div ng-include="'components/mainmenu/mainmenu.html'" id="mainMenuWrapper"></div>
    <div id="workspace" ng-style="heightMenuExcluded">
        <div ng-include="'components/tools/tools.html'" id="toolsWrapper"></div>
        <div ng-include="'components/canvas/canvas.html'" id="canvasWrapper"></div>
    </div>
</div>

指令

'use strict';

    angular.module('photoedit')
            .directive('workspaceHeight', ['$window', '$timeout',
                function ($window, $timeout) {
                    return {
                        restrict: 'A',
                        link: function (scope, element, attrs) {

                            var window = angular.element($window),
                                body = angular.element('body'),
                                mainMenu = element.find('#mainMenuWrapper'),
                                workspace = element.find('#workspace')
                            ;

                            console.log(window);
                            console.log(body);
                            console.log(mainMenu);
                            console.log(workspace);

                            console.log(window.height());
                            console.log(body.height());
                            console.log(mainMenu.height()); // null
                            console.log(workspace.height());


                            window.on('resize', function(){
                                var height = workspace.css('height', body.height() - mainMenu.height());
                                scope.heightMenuExcluded = {'height':height + 'px'};
                            });
                            window.trigger('resize');


                        }
                    };
                }
            ]);

我无法访问mainMenu height属性...

1 个答案:

答案 0 :(得分:1)

修改: Plunker已添加。

在你的情况下,我将指令负责重新调整包含标题和画布的元素的大小。像这样:

<canvas-app-wrapper>
    <header></header>
    <canvas></canvas>
</canvas-app-wrapper>

该指令如下所示:

app.directive('canvasAppWrapper', function() {
    return {
        restrict: 'E',
        link: function(scope, el) {
            var canvas = el.find('canvas');
            var header = el.find('header');
            var headerHeight = header[0].offsetHeight;

            canvas[0].height = el[0].offsetHeight - headerHeight;
            canvas[0].width = el[0].offsetWidth;

        }
    }
})

我觉得这是最有意义的,因为画布独立于标题,不应该知道它的存在。您可以在包装器中计算所需的大小,并将其传递给canvas指令或直接从包装器更改它。

通常,指令之间相互通信的最佳方式是通过隔离范围。每个指令应尽可能独立于其他指令(以启用重用)。指令应该通过其范围初始化接受参数,仅此而已。当然,使用服务是好的,但应该以不妨碍组件的方式完成。