在启动和监听器上进行Ember js网络连接检查

时间:2014-03-02 01:03:23

标签: javascript ember.js offline-browsing

首先,我知道这个问题Display online and offline (e.g. airplane) mode in an Ember.js App,但这并没有解决我遇到的所有问题。这个问题的答案使用了Heyoffline.js,这是一个很棒的库(这是JSbin使用的),但是它不会检查Ember应用程序“启动”时的连接状态,只有当我关闭我的wifi时才会这样做使用该应用程序。我正在创建一个离线/在线兼容的Ember应用程序,我只需要知道启动状态是什么,我需要完全控制“胆量”,意味着UI,视图等... Heyoffline.js做了太多对你而言。

非常简单地说,我需要启动一个Ember应用程序:

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 - 必须工作“ember方式”,可能是Ember.Evented或一些Pub / Sub设置。我可以破解它,尽量不这样做。
  5. 希望它比window.onLine更加万无一失 - 只有真正检查你是否连接到局域网或路由器,而不是“真正”检查互联网
  6. 我处在一个非常特定的环境中,特别是Webkit,我不需要IE或旧的浏览器支持。
  7. 我没有其他的预先要求,我会完全废弃我当前的设置。
  8. 任何想要分享的想法,建议或小块都将不胜感激。

1 个答案:

答案 0 :(得分:1)

一个问题是:

if(App.isOffline){//&lt; ---这总是回归,doh

您应该将其称为函数,而不是仅仅访问它。函数是一个真正的值,但你想要的是函数的结果。

现在,其余的功能。将它封装在服务上并使其可用于其他控制器/视图是有意义的。为简单起见,我将它作为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中,然后可以将其注入控制器,以便将此类问题从应用程序中移除,但这可能需要回答第二个问题。

希望这有帮助