给angularJs的service建模
先回顾一下我们遇到的问题:
通过一个dialogService创建对话框,并将该service的参数数据通过resolve的方式传递给对话框的controller。
controller解析数据后放置在$scope上,供内部的directive使用。
现在希望在dialog打开后,如果对话框页面内的部分再次调用到这个service时,可以复用原来的对话框,仅仅将数据更新。controller内部的directive已经可以通过$digest自动更新view,只需要让dialogService把新的数据传递给controller。
先想到一个简单的方案:
既然service要区分第一次打开和复用的情况,就让service暴露一个接口,controller把自己注册进去,随后service就可以通过controller上提供的方法去更新数据。
然而,这种方法对于单例的service而言,保存一个controller的实例存在内存泄露的风险。而且service的职责不清晰,来回调用传递数据也过于复杂。
于是我们换了一个思路:
1. 对于dialogService本身建模,令用户代码持有service实例对象,每次打开新对话框时创建一个新的service实例。service实例与对话框相对应。
2. 既然要求一次打开dialog后可以复用,就意味着dialog是一个单例,可以采用单例模式。用户代码访问service的工厂获取service创建或者获取service实体。
3. 进一步的,将数据的holder放置在service定义的部分,service可以通过闭包来更新数据,service再将数据的应用resolve给controller,controller就可以直接看到更新过的数据,而不需要来回赋值。
下面给出一个大致的实现
module.factory('dialogService', function(){
function DialogService(){
this.dialogParam = {};
}
DialogService.prototype.createDialog = function(data){
this.dialogParam.data = data;
// call functions to open the dialog
// resolve the this.dialogParam to the controller
};
DialogService.prototype.onDialogClose = function(){
// 清除工作,需要将serviceInstance和dialogParam清空。
};
var serviceInstance;
return {
getService: function(){
if (!serviceInstance){
serviceInstance = new DialogService();
}
return serviceInstance;
}
};
});
可以看到在以上代码中,基本只是一个单例模式的实现。这个和在java里面差不多,而且还要简单,因为javascript没有多线程的问题。
调用关系和职责划分也更清晰。
浙公网安备 33010602011771号