Ember.js - 如何将对象值与控制器的属性绑定

时间:2014-05-16 13:55:32

标签: object ember.js binding controller observers

Ember.js新手问题:

将对象值与控制器的属性绑定的最佳方法(如果可能)是什么?

假设我们有这段代码:

App.Stalker = Ember.Mixin.create({
  init: function() {
    this._super();
    var props = this.get('watchProperties');
    Ember.assert("watchProperties should be an array", Ember.isArray(props));
    props.forEach(function(property) {
      Ember.addObserver(this, property, this, '%@Changed'.fmt(property));
    }, this);
  },

  willDestroy: function() {
    this._super();
    this.get('watchProperties').forEach(function(property) {
      Ember.removeObserver(this, property, this, '%@Changed'.fmt(property));
    }, this);
  }
});

App.states = Ember.Object.createWithMixins(App.Stalker, {
  watchProperties: 'state'.w(),
  stateChanged: function() {
    console.log("idle changed");
  }
});

App.IndexController= Ember.Controller.extend({
  state: *// How do I bind with App.states.state*,
  contentDidChange: function() {
    console.log('idle !!!');
    this.transitionToRoute("idle");
  }.observes('state')
    });

// Here is use a jQuery plugin to check if the User of the app goes in the idle mode

App.IndexView = Ember.View.extend({
  didInsertElement : function(){
    self = this;
    this._super();
    $( document ).on( "idle.idleTimer", function(event, elem, obj){
        App.states.set('state', 'idle');
        console.log(self.get("controller.state"));
        });
  }
});

1 个答案:

答案 0 :(得分:1)

这将使你的例子工作......有点。

App.ApplicationRoute = Ember.Route.extend({
  actions: {
    lazyState: function (state) {
      console.log("lazyState: " + state);
      switch (state) {
        case "idle":
          this.transitionTo("lazy");
          break;
        case "active":
          this.transitionTo("index");
          break;
        default: throw new Error("Invalid state");
      }
    }
  }
});

App.LazyView = Ember.View.extend({
  _handler: null,
  didInsertElement : function(){
    console.log("insert lazy");
    var self = this;
    this._super();
    var handler = function (event, elem, obj) {
      Ember.run(function () {
        self.get("controller").send("lazyState", "active");
      });
    };
    $(document).on("active.idleTimer", handler);
    this.set("_handler", handler);
  },
  willDestroyElement: function() {
    $(document).off("active.idleTimer", this.get("_handler"));
    this.set("_handler", null);
  }
});

// Index Views functionality

App.IndexView = Ember.View.extend({
  _handler: null,
  didInsertElement : function(){
    console.log("insert index");
    self = this;
    this._super();
    var handler = function (event, elem, obj) {
      Ember.run(function () {
        self.get("controller").send("lazyState", "idle");
      });
     };
    $(document).on("idle.idleTimer", handler);
    this.set("_handler", handler);
  },
  willDestroyElement: function () {
    $(document).off("idle.idleTimer", this.get("_handler"));
    this.set("_handler", null);
  }
});

JSBin

我把它鞭打成一个正常工作的命令,但我几乎没有把它作为答案发布。 IMO这既不是最出色的实施方式,也不是正确的方法。要从此处继续,您需要将IndexView实施重构为某种Mixin,或将其移至ApplicationView。然后你需要在进入'空闲'模式时实现一些保存当前位置的方法,所以你不要总是回到索引...

保持足​​够长的时间,我认为你会达到我认为正确的解决方案:根本不使用路线和视图。

根据您的描述,您只需在用户空闲时显示某种屏幕保护程序。您无需为此切换路由。在待机屏幕上没有用户交互。相反,只需将您想要的空闲屏幕DOM渲染到主布局中的隐藏div中,并在用户空闲时使用jQuery显示/隐藏它。或者将其放入#if isIdle块并从全局事件处理程序更改isIdle