2012-06-23 29 views
2

我正在嘗試制定正確的模式以用於使用AJAX調用進行初始化的單身人士。這是我已經工作的一個簡單例子。帶AJAX初始化程序設計模式的javascriptMVC單身人士

它按預期工作,但我有一種感覺,這不是「正確的」方式,並且有一些方法可以將初始化程序的回調掛接到當前運行的ajax請求的成功調用中,而且我擔心那裏可能是陣列方法的競爭條件。我在正確的軌道上嗎?

var singletonObj; 
$.Class("SingletonTest", { 
    init: function(onSuccess) { 
    if (singletonObj) { 
     if (singletonObj.ajaxLoaded) { 
     onSuccess(singletonObj); 
     } 
     else { 
     singletonObj.callbacks.push(onSuccess); 
     } 
    } 
    else { 
     singletonObj = this; 
     singletonObj.callbacks = new Array(onSuccess); 
     singletonObj.count=0; 

     $.ajax({ 
     url: "/path/to/json/config", 
     method: "GET", 
     success: function (res) { 
      singletonObj.data = res.meta_data; 
      singletonObj.ajaxLoaded = true 

      singletonObj.callbacks.forEach(function(callback) { 
      callback(singletonObj); 
      }); 
     } 
     }); 
    } 
    }, 
    counter: function() { 
    return this.count++; 
    } 
}); 

new SingletonTest(function(obj) { console.log("First call: "+obj.counter()) }); 
new SingletonTest(function(obj) { console.log("Second call: "+obj.counter()) }); 
new SingletonTest(function(obj) { console.log("Third call: "+obj.counter()) }); 

還是有更簡單的方法來做到這一點?我在這裏想念什麼概念會讓生活變得更輕鬆?

+0

可以站在提高評論的相關性! – cliveholloway

+2

此外,forEach不會在IE中工作,應避免使用新的Array()(改爲編寫[onSuccess])。 – noah

回答

2

既然你正在尋找這裏的「正確」的方式是一些一般注意事項:

  1. 你並不需要一個單例類(JavaScript是不是Java)。只需將其設置爲全局對象或更好的功能即可。

  2. $.Deferred是你的朋友。 $.ajax返回一個承諾。

這裏是單身的功能​​模式:實現功能:

// creates a lazy singleton from a factory function 
function singleton(factory) { 
    var deferred; 
    return function() { 
     return deferred || (deferred = factory()); 
    }; 
} 

// declare your specific singleton 
var SingletonTest = singleton(function() { 
    return $.ajax({ 
     url: "/path/to/json/config", 
     method: "GET" 
    }).pipe(function(obj) { 
     // pipe lets you modify the result 
     // here we add the counter method 
     var count = 0; 
     obj.counter = function() { 
      return count++; 
     }; 
     return obj; 
    }); 
}); 

// use it 
SingletonTest().then(function(obj) { 
    console.log("First: "+obj.counter()); 
}); 

SingletonTest().then(function(obj) { 
    console.log("Second: "+obj.counter()); 
}); 

如果你發現自己使用這個模式很多,有一個JMVC plugin(我的主要作者披露)依賴注入的形式。

如果你使用Inject,它應該是這樣的:

var cache = Inject.cache(); 
var Injector = Inject(
    cache.def('SingletonTest',function() { 
     return $.ajax({ 
      url: "/path/to/json/config", 
      method: "GET" 
     }).pipe(function(obj) { 
      var count = 0; 
      obj.counter = function() { 
       return count++; 
      }; 
      return obj; 
     }); 
    }) 
); 

var logCount = Injector('SingletonTest',function(obj,message) { 
    console.log(message+obj.counter()); 
}); 

logCount("First:"); 
logCount("Second:"); 

對於大型項目有很多單身或者只是延期數據,注射鱗比的全局變量更好。

+0

非常感謝您的詳細回覆。我仍然在學習現代的JS設計模式,而這種模式讓我的頭腦太過分了。 – cliveholloway