djx0126

导航

给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没有多线程的问题。

调用关系和职责划分也更清晰。

posted on 2014-07-14 22:51  djx0126  阅读(289)  评论(0)    收藏  举报