2016-02-01 66 views
2

在我的代码中,我尝试从缓存中加载模板。如果模板不在缓存中 - 通过ajax从服务器加载模板。加载完成后,我想将模板缓存并返回。这里是:如何从缓存或ajax加载模板返回模板?

var manager = function() { 

    return { 

     cache: [], 
     getTemplate: function (templateId) { 

      this.templateId = templateId; 

      if (this.cache[this.templateId]) { 
       return this.cache[this.templateId]; 
      } 

      return this.loadTemplate(); 
     }, 

     loadTemplate: function() { 

      var 
      self = this; 

      $.get('/assets/templates/' + this.templateId + '.html', function (templateHtml) { 

       self.cache[self.templateId] = templateHtml; 
       return self.getTemplate(self.templateId); 
      }); 
     } 
    } 
} 

var 
manager = manager(); 

$('body').append(manager.getTemplate('template')); 

我知道我的代码不工作,因为在函数loadTemplate结束后ajax请求完成。我认为代码可以用延迟对象修复,但不知道如何。任何人都可以帮助我找到解决方案吗?

回答

2

有实现目标的双向:

  1. Promises(有很多库/垫片)。我把它改写到ES6只是为了学习:

    let manager = function() { 
    
        return { 
    
         cache: [], 
    
         getTemplate(id) { 
          let cache = this.cache; 
    
          return new Promise((resolve, reject) => { 
           if (cache[id]) { 
            resolve(cache[id]); 
           } else { 
            this.loadTemplate(id) 
             .then(template => { 
              cache[id] = template; 
              resolve(template); 
             }) 
             .fail(reject); 
           } 
          }); 
         }, 
    
         loadTemplate(id) { 
          return $.get('/assets/templates/' + id + '.html'); 
         } 
        } 
    }; 
    
    let manager = manager(); 
    
    manager.getTemplate('template').then((template) => { 
        $('body').append(template); 
    }); 
    
  2. 回调:

    let manager = function() { 
    
        return { 
    
         cache: [], 
    
         getTemplate(id, cb) { 
          let cache = this.cache; 
    
          if (cache[id]) { 
           cb(cache[id]); 
          } else { 
           this.loadTemplate(id) 
            .then(template => { 
             cache[id] = template; 
             cb(template); 
            }); 
          } 
         }, 
    
         loadTemplate(id) { 
          return $.get('/assets/templates/' + id + '.html'); 
         } 
        } 
    }; 
    
    let manager = manager(); 
    
    manager.getTemplate('template', (template) => { 
        $('body').append(template); 
    }); 
    
+0

非常感谢,这是我需要的! – Evgeniy

1

当您通过AJAX获取模板时,只能在AJAX成功时追加结果。所以你需要传递append逻辑作为回调。检查下面的代码。

var manager = function() { 

    return { 

     cache: [], 
     getTemplate: function (templateId,callback) { 

      this.templateId = templateId; 

      if (this.cache[this.templateId]) { 
       callback(this.cache[this.templateId]); 
      } 

      this.loadTemplate(callback); 
     }, 

     loadTemplate: function(callback) { 

      var 
      self = this; 

      $.get('/assets/templates/' + this.templateId + '.html', function (templateHtml) { 

       self.cache[self.templateId] = templateHtml; 
       callback(templateHtml) 
      }); 
     } 
    } 
} 

var 
manager = manager(); 

manager.getTemplate('template',function(result) { 

$('body').append(result); 
}); 

您可能不需要2个函数来执行此操作。所以,你可以把它作为一个

+0

非常感谢您对您answear! – Evgeniy

2

这里是你会怎么做,支持所有主要的浏览器,太缓存请求。这样你只会为每个模板执行一次请求。 (其他答案只缓存响应)。

var Manager = function() { 
 

 
    return { 
 

 
     cache: [], 
 

 
     getTemplate(id) { 
 
     var that = this; 
 

 
     if (that.cache[id] && that.cache[id].then){ 
 
      console.log("Promise cache"); 
 
      return that.cache[id]; //return promise from cache 
 
     } 
 

 
     return $.Deferred(function() { 
 
      var def = this; 
 
      
 
      if (that.cache[id]) { 
 
       console.log("Retrieved from cache!"); 
 
       return def.resolve(that.cache[id]); //return cached template 
 
      } 
 

 
      that.cache[id] = def; //Cache promise 
 
      
 
      console.log("Retrieving template..."); 
 
      that.loadTemplate(id).then(function(template) { 
 
       that.cache[id] = template; 
 
       def.resolve(template) 
 
      }).fail(function() { 
 
       def.reject(); 
 
      }); 
 

 
      return that.cache[id]; //return promise 
 
      
 
     }).promise(); 
 

 
     }, 
 

 
     loadTemplate(id) { 
 
     return $.get('https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'); 
 
     } 
 
    } 
 
}; 
 

 
var manager = Manager(); 
 

 
manager.getTemplate('template').then(function(template){ 
 
    console.log("loaded 1"); 
 
}); 
 

 
//This will use the promise from the first call (1 Request only) 
 
manager.getTemplate('template').then(function(template){ 
 
    console.log("loaded 2"); 
 
    manager.getTemplate('template').then(function(template){ 
 
     console.log("loaded 3"); //This will be retrieved fully from cache 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

+1

也谢谢你:)现在我可以用所有回答完成我的代码 – Evgeniy