我正在构建像角度的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;
}]);
答案 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)
我会实现以下逻辑:
growl
在growlProp
&amp;上定义了一些属性$rootScope
。每次调用growl.add $rootScope.growlProp
因此,指令对服务&amp;服务对directve一无所知。
与观察者相关的额外开销是最小的。