2015-02-17 64 views
0

我想问一下在Angular应用程序中处理内部通信的最佳方法是什么。正确的方法 - Angular JS中的指令之间的通信

的例子如下:

我有一个响应顶层菜单中,全屏画布和控制其绝对定位在画布的角部的全屏应用。画布应填充几乎整个屏幕(不包括顶部菜单的空间)。

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

我有一个指令放置在画布元素应该适当调整画布的大小。

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

  • 我应该传递一个额外的参数给指令吗?
  • 我应该创建一个可以广播这些信息的全球服务吗?
  • 我应该让父母控制员来处理这个问题吗?
  • 还是应该使用完全不同的方法?

对于应用架构模式,角度官方文档似乎不是很有用。

谢谢。

UPDATE 示例代码

HTML块

<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属性...

+0

我会去与发布/订阅。您可以发布全球(文档级)或更具体的事情。在我看来,这是组件之间沟通的最佳方法。 – vsync 2015-02-18 00:34:28

回答

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指令或直接从包装器中更改它。

一般来说,指令彼此间通信的最佳方式是通过隔离范围。每条指令应尽可能独立于其他指令(以便重用)。一个指令应该通过它的作用域初始化接受参数,除此之外,当然,使用服务是很好的,但应该以一种不会让你的组件混乱的方式来完成。

+0

谢谢你的回答。我可以问我应该如何将菜单高度传递给包装器指令?如何正确地做到这一点?谢谢 – tomexx 2015-02-18 00:07:05

+0

我已经添加了一个工作示例。您可以看到画布高度已正确设置为200px,包装为300px,标题为100px。 – Mosho 2015-02-18 00:32:26

+0

谢谢你的回答。我已经添加了我的代码。你可以请重新访问它吗?事情是我无法访问也是儿童指令的mainMenu元素。 – tomexx 2015-02-18 23:15:34