MyNamespace.Facebook.coffee:
namespace 'MyNamespace', (exports) ->
exports.FacebookAPILoader = class
constructor: (@appId, @channelFileUrl) ->
@init()
init: (fbAPILoadedCallback) ->
#FB triggers/calls window.fbAsyncInit() after the API javascript loads:
window.fbAsyncInit = () =>
@initFb()
fbAPILoadedCallback() if fbAPILoadedCallback?
return
@loadAPI()
loadAPI: () ->
((d) ->
id = 'facebook-jssdk'
ref = d.getElementsByTagName('script')[0]
return if d.getElementById id
js = d.createElement 'script'
js.id = id
js.async = true
js.src = "//connect.facebook.net/en_US/all.js"
ref.parentNode.insertBefore js, ref
)(document)
# Set app specific settings here:
initFb: () ->
fbConfig =
appId: @appId
channelUrl: @channelFileUrl
status: true
cookie: true
xfbml: true
FB.init fbConfig
这就是我在视图中加载 api 的方式: //MyView.cshtml:
@using (Script.Foot()) {
var settingsReader = new System.Configuration.AppSettingsReader();
var facebookAPIAppId = settingsReader.GetValue("Facebook_API_AppId", typeof(string));
var hostName = settingsReader.GetValue("EnvHostname", typeof(string));
<script type="text/javascript">
var myFb;
$(document).ready(function () {
myFb = new MyNamespace.FacebookAPILoader(
'@Html.Raw(facebookAPIAppId)'
, '//@Html.Raw(hostName)/modules/myapp/channel.html'
);
});
</script>
}
</body>
Jquery 在结束标记之前加载。我有两个问题:
我在这里加载它的方式有什么问题吗?我相信它会在 jquery 触发文档“就绪”事件后异步加载——对吗?有没有一种性能更好的方法?
设置此模块以便我可以传入将在 fbAsyncInit() 中执行的任意回调的最佳方法是什么?我在 CMS (Orchard) 驱动的网站中使用它,并且我可能在同一个 HTTP 请求中有多个视图,希望添加它们自己的自定义回调,这些回调应该作为 fbAsyncInit() 的一部分运行。我该如何做到这一点?我知道我可以只传入一个回调数组,但我不确定的部分是如何确保给定页面上的所有不同功能都可以反映他们的 Facebook 相关代码是什么,以及如何确保FacebookAPILoader.init() 仅在所有这些 FB 小部件的回调和 DOM 元素并且一切都准备好与之交互之后运行。
更新:
我想我会以与谷歌分析异步跟踪_gaq
对全局命名空间中的变量相同的方式执行此操作。任何需要 Facebook API 交互的代码都可以将回调推送到 _gaq 样式队列中,FacebookAPILoader 模块将在准备好时拉出该队列。这是一种天真的方法吗?在调用fbAPILoadedCallback ()之后,我的代码是否会尝试添加到 _gaq 样式队列中?