Ember的reopen()函数是否适用于Ember-CLI中已编译的ES6模块?

时间:2015-02-19 17:28:36

标签: ember.js ember-cli

我正在努力将Ember.js应用移植到ember-cli。

我的应用程序是一个增强的桌面游戏,在其中,我有一个余烬状态StateMachine子类,它管理涉及在两个玩家之间来回传递游戏的动作。

在该子类中,我调用reopen()以定义绑定到状态机的currentState.name的方法:

PassManager.reopen({
  isPassing : function(){
    return this.get("currentState.name") == "pass";
  }.property("currentState.name")
});

请参阅此处的上下文:https://github.com/atduskgreg/SneakGame/blob/ember-cli-refactor/app/models/pass-manager.js#L49

然后我在我的模板中的if语句中调用该函数:

<h1>Player character assignments</h1>
{{#if PassManager.isPassing}}
  {{partial 'pass'}}
{{else}}
  <p>You are {{current-player-color}}.</p>
  <p><button {{action 'next'}}>Got it</button></p>
{{/if}}

https://github.com/atduskgreg/SneakGame/blob/ember-cli-refactor/app/templates/character-assignment.hbs#L2

当PassManager处于“通过”状态时,它应返回true并显示相关的部分,当它为假时,它应显示此处所见的其余模板。

这在移植到ember-cli之前工作正常,但确实发出了与此问题相关的弃用警告:http://emberjs.com/guides/deprecations/#toc_global-lookup-of-views

我现在已将应用程序移植到ember-cli,现在不再评估PassManager.isPassing了。它总是返回false,并且它内部的console.log()语句永远不会被执行。

我刚开始使用ES6模块,并且想知道我是否在导出PassManager时出错了,或者如果有一些更根本的原因,reopen()将无法在导出的模块上运行。在我的pass-manager.js文件的底部,我有:

export default PassManager;

在我在我的应用程序中导入它的地方正确找到了PassManager。这只是使用reopen()定义的这个函数,它不被调用。

1 个答案:

答案 0 :(得分:1)

PassManager不是Ember.StateManager的子类,而是它的一个实例,因为你使用的是create而不是extend。重新打开可以与实例一起使用,但适用于实例所在的类。因此,顺序是不同的:实例方法会覆盖类方法。因此,您的Ember.StateManager.create中的isPassing版本将覆盖PassManager.reopen中的版本。

尝试像这样构建代码:

import Ember from "ember";
import Game from "./game"

var PassManagerClass = Ember.StateManager.extend({
  reset : function(){
    console.log("PassManagerClass.reset()");
    this.set('players', this.get('gamePlayers'));
    this.set('playerIdx', 0);
    this.transitionTo("pass");
  },

  next : function(){
    if(this.get('currentState.name') == "pass"){
      this.transitionTo("act");
    } else {
      if(this.get('playerIdx') == Object.keys(this.get('gamePlayers')).length - 1){
        this.transitionTo("done");
      } else {
        this.transitionTo("pass");
      }
    }
  },

  isPassing : function(){
    console.log("here");
    return true;
  }.property()
});

PassManagerClass.reopen({
  isPassing : function(){
    console.log("isPassing: " + this.get("currentState.name"));
    return this.get("currentState.name") == "pass";
  }.property("currentState.name")
});

var PassManager = PassManagerClass.create({
  initialState : 'pass',
  playerIdx : 0,
  gamePlayers: Game.players,

  pass : Ember.State.create({
    enter: function(stateManager) {
      console.log("PM entering pass");
    } 
  }),

  act : Ember.State.create({
    enter: function(stateManager) {
      console.log("PM entering act");
    },
    exit: function(stateManager) {
      PassManager.playerIdx = PassManager.playerIdx + 1;
    } 
  }),

  done : Ember.State.create({
    enter: function(stateManager) {
      console.log("PassManager done");
    } 
  }),
});

export default PassManager;

注意:这只是为了说明,并指出正确的方向。我没有测试过这个。