javascript - 如何构建操纵 DOM 的 Angular 因子/服务

标签 javascript angularjs dom angularjs-directive angular-services

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

工厂和指令之间如何最好地沟通?

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

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

作为引用,我尝试过其他选项:

A) 让指令监视服务,例如

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

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

B) 通过 Routescope 或 dom/window 上的事件绑定(bind)发送“事件”。看起来没有棱 Angular

由于这两个选项看起来都不太好,所以我使用了下面的一个,但它仍然感觉很糟糕。 register 函数意味着指令和工厂紧密耦合。但话又说回来,从使用的 Angular 来看,它们是紧密结合在一起的——一个没有另一个就不好。

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

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

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;
}]);

最佳答案

我会让你的咆哮服务决定显示什么,而不是指令。因此,该服务会处理任何计时器、状态等来决定何时隐藏/显示消息。然后,该服务公开该指令简单绑定(bind)到的消息集合。

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

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

然后在指令模板中:

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

关于javascript - 如何构建操纵 DOM 的 Angular 因子/服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25920694/

相关文章:

javascript - 使用特殊字符时,服务器响应会奇怪地进行编码/解码

javascript - 使用 angularJS 服务将 `setInterval` 转换为 AngularJS

javascript - 将 Jquery 插件转换为 Angular 指令

java - 解析器-如何读取文件?

javascript - 在 React 类组件中使用 ResizeObserver

javascript - 为什么不是 (function(){}());工作,但 window.onload 是?

javascript - 删除列表中的行

javascript - Ng-click 不起作用

javascript - 为什么带有 <br> 的 "innerHTML"属性不创建新行?

javascript - 使用原型(prototype)获取和替换 <a> 标签的 href 属性值