2014-03-02 17 views
2

首先,我知道这个问题Display online and offline (e.g. airplane) mode in an Ember.js App但这并不能解决我遇到的所有问题。这个问题的答案使用了Heyoffline.js,这是一个伟大的库(这是JSbin使用的),但它不检查Ember应用程序的“启动”时的连接状态,只有当我关闭我的无线网络时使用应用程序。我正在创建一个离线/在线兼容的Ember应用程序,我只需要知道启动时状态是什么,我需要完全控制“胆量”,这意味着用户界面,视图等... Heyoffline.js确实太多了为你。Ember js网络连接检查在启动和听众

简单说来,我要火了灰烬应用:

window.App = Ember.Application.create({ 
LOG_TRANSITIONS: true, 
LOG_VIEW_LOOKUPS: true, 
service: null, 
isOffline: function() { 
    var networkCheck = navigator.onLine ? true : false; 
    return networkCheck; 
}, 
ready: function() { 
    this.set('service', App.HeyOffline.create()); 
    Ember.debug("App ready!"); 
} 
}); 

App.HeyOffline = Ember.Object.extend({ 
service: null, 
init: function() { 
    this.set('service', new Heyoffline({ 
     noStyles: true, 
     prefix: "network", 
     text: { 
      title: "No Internet Connection", 
      content: "Your experience will be limited, it's suggested that you connect to the internet", 
      button: "Continue Anyway." 
     } 
    })); 
    this.set('service.options.onOnline', this.offline); 
    this.set('service.options.onOffline', this.online); 
}, 
online: function() { 
    App.set('isOffline', false); 
    Ember.debug('Online'); 
}, 
offline: function() { 
    App.set('isOffline', true); 
    Ember.debug('Offline'); 
} 
}); 

App.ApplicationRoute = Ember.Route.extend(); 

view.js

App.NetworkView = Ember.View.extend({ 
layoutName: "_network_error", 
classNames: ['network-error', 'flash-message'], 
classNameBindings: ['isHidden:hide:show'], 
isHidden: true, 
networkFail: function() { 
    var self = this; 
    console.log("Network Failure"); 
    this.set('isHidden', false); 
    Ember.run.next(function() { 
     setTimeout(function(){ 
      self.set('isHidden', true); 
     }, 3000); 
    }); 
}, 
didInsertElement: function() { 
    var self = this; 
    Ember.run.next(function() { 
     if(App.isOffline) { // <--- THIS ALWAYS RETURNS TRUE, doh 
      self.networkFail(); 
     } 
    }); 
} 
}); 

application.hbs

{{outlet}} 
{{outlet modal_dialog}} 
{{outlet modal_status}} 
{{outlet debug}} 

{{#view App.NetworkView }} {{/view }} 

还有很多东西要我的应用程序,但我认为我已经拿出了所有相关的部分。我并不是说它必须这样做,我唯一的要求是:

  1. 必须在启动时检查并设置“某些东西”,以便在需要时显示消息。我并不是说它必须推迟阅读任何事情,从用户体验/用户界面的角度来看,一旦应用“准备就绪”或运行循环结束,消息就会弹出。
  2. 我必须控制消息UI,它必须是“Emberized”(我正在考虑视图或组件),它将从顶部元素向下滑动(如Facebook移动连接警告)。
  3. 必须有某种听者的(如果我失去了我的连接,我可以弹出的小消息) - Heyoffline.js做这个奇妙
  4. 必须Emberized - 必须努力“余烬方式”,也许灰烬.Evented或一些Pub/Sub设置。我可以破解它,试图不这样做。
  5. 会喜欢它比window.onLine更傻一点 - 只有真正检查你是否连接到局域网或路由器,而不是“真正”检查互联网
  6. 我在一个非常具体的环境中,Webkit专门,我不需要IE浏览器或旧浏览器支持。
  7. 我没有其他的预先要求,我会很好地摧毁我目前的设置完全。

任何人想分享的想法,建议或掘金将不胜感激。

回答

1

的一个问题是:

如果(App.isOffline){// < ---这总是返回true,卫生署

你应该把它作为一个功能,而不仅仅是访问它。函数是一个真值,但你想要的是函数的结果。

现在,其余的功能。将它封装在一个服务上并使其可用于控制器/视图的其余部分是有意义的。为了简单起见,我将它作为ApplicationController的一部分。

App.ApplicationController = Ember.Controller.extend({ 
    isOnline: true, // assume we're online until proven wrong 
    init: function() { 
    updateNetworkStatus(); 
    }, 

    updateNetworkStatus: function() { 
    var appController = this; 
    if (!navigator.onLine) { 
     this.set('isOnline', false); 
     return; // return early, no point in pinging the server if we have no LAN 
    } 
    Ember.$.get('myserver.com/status').done(function() { 
     // todo: consider checking the result 
     appController.set('isOnline', true); 
    }).fail(function() { 
     appController.set('isOnline', false);  
    }).always(function() { 
     Ember.run.later(appController, 'updateNetworkStatus', 60000); 
    }); 
    } 
}); 

我们还是检查navigator.online,但如果这是真的,我们不承担我们一路到服务器的连接。我们检查。一旦我们得到响应,我们更新标志并不断更新该标志。

从其他控制器,我们可以简单地添加一个依赖项到应用程序控制器。

App.OtherController = Ember.Controller.extend({ 
    needs: ['application'], 
}); 

,然后做某些动作之前使用它的属性或作为检查:

App.OtherController = Ember.Controller.extend({ 
    needs: ['application'], 
    canEdit: function() { 
    return this.get('controllers.application.isOnline'); 
    }.property('controllers.application.isOnline') 
}); 

或者从您的视图

{{controllers.application.isOnline}} 

希望这有助于。正如我所说的,我通常会将其封装成一个service,然后可以将其注入到控制器中,以便将这种类型的问题从应用程序中移除,但这可能需要回答第二个问题。

希望这会有所帮助