如何构造操纵DOM的角度因子/服务

时间:2014-09-18 19:17:56

标签: javascript angularjs dom angularjs-directive angular-services

我正在构建像角度的UI一样的咆哮。我想将它作为工厂(或服务)公开,以使其在我的控制器中可用。调用growl.add会导致DOM发生变化,因此看起来我应该有一个指令来处理它,而不是在工厂中直接进行DOM操作。假设工厂指令组合是最好的选择(如果这不是一个好的假设,请纠正我),问题是:

如何在工厂和指令之间进行最佳沟通?

具体来说,如何最好地将工厂发送到指令?其他问题很好地涵盖了通过一次性回调以另一种方式发送信息。

见下面的工作示例。我怀疑有更好的方法..

作为参考,我玩过其他选项:

A)让指令观察服务,例如

$scope.$watch(function(){
     growl.someFunctionThatGetsNewData()},
  function(newValue){
    //update scope
  })

但这意味着someFunctionThatGetsNewData会在每个摘要周期中被调用,这看起来很浪费,因为我们知道数据只会在growl.add上被更改

B)通过routescope或通过dom / window上的事件绑定发送'event'。似乎没有棱角分明

由于这些选项都不好看,我正在使用下面的那个,但它仍然感觉很乱。 register函数意味着指令和工厂紧密耦合。但是再次从用途的角度来看,他们 紧密绑定 - 一个对另一个没有好处。

似乎理想的解决方案将涉及声明在其声明(以及可能的功能范围)中包含指令的工厂(或服务),以便它公开单个公共接口。两个独立的公开声明的组件完全相互依赖,并且在接口中具有紧密耦合似乎很蹩脚。

工作示例 - 但必须有更好的方法..

vpModule.directive('vpGrowl',['$timeout', 'growl', function ($timeout, growl) {
return {
  template: '<div>[[msg]]</div.',
  link: function($scope, elm, attrs) {

     growl.register(function(){
        $scope.msg = growl.msg;
     });

     $scope.msg = growl.msg;

  }
};   
}]);


vpModule.factory('growl', ['$rootScope', '$sce', function($rootScope, $sce) {

  var growl = {};
  growl.msg = '';
  var updateCallback = function(){};

  growl.add = function(msg){
    growl.msg = msg;
    updateCallback();
  };

  growl.register = function(callback){
    updateCallback = callback;
  };

  return growl;
}]);

2 个答案:

答案 0 :(得分:1)

我希望你的咆哮服务决定展示什么,而不是指令。因此,该服务处理任何计时器,状态等,以决定何时隐藏/显示消息。然后,该服务公开指令简单绑定的消息集合。

该指令可以注入服务并简单地将其放在范围内,然后将ng-repeat绑定到服务的集合。是的,这确实涉及手表,但你真的不需要担心像这样的单个手表的性能。

link: function(scope, elm, attrs) { scope.growl = growl; // where 'growl' is the injected service }

然后在指令模板中:

<div ng-repeat="msg in growl.messages"> ... </div>

答案 1 :(得分:0)

我会实现以下逻辑:

  1. 服务growlgrowlProp&amp;上定义了一些属性$rootScope。每次调用growl.add
  2. 时更新它
  3. 指令设置观察者$rootScope.growlProp
  4. 因此,指令对服务&amp;服务对directve一无所知。

    与观察者相关的额外开销是最小的。