1

我的问题的示例代码在这里。这是一个简单的 Ember 应用程序,默认显示包含 TextField 的 SearchView。

当用户输入一些文本并按 Enter 键时,我想通过在文本框中输入的值转换到另一个状态(displayUserProfile)。

起初,在 Textbox 的insertNewline回调中,我调用了应用程序路由器的transitionTo方法,将值作为参数对象的一部分传递:

App.SearchTextFieldView = Em.TextField.extend({
  insertNewline: function() {
    App.router.transitionTo('displayUserProfile', {
      username: this.get('value')
    });
  }
});

这很好用,但后来我注意到 pangratz 对有关无限滚动的问题的回答使用了不同的方法。相反,他调用视图控制器上的一个方法,该控制器又调用控制器目标(即路由器)上的一个方法。

这将我的代码更改为:

App.SearchTextFieldView = Em.TextField.extend({
  insertNewline: function() {
    Em.tryInvoke(this.get('controller'), 'displayUserProfile', this.get('value').w());
  }
});

App.SearchController = Em.Object.extend({
  displayUserProfile: function(username) {
    this.get('target').transitionTo('displayUserProfile', {
      username: username
    });
  }
});

我的问题是:哪种方法更好?直接从视图调用transitionTo或将其委托给视图的控制器?

4

2 回答 2

3

我会推荐一种不同的方法。insertNewLine应该触发一个由路由器处理的动作,然后路由器将转换其状态。

App.SearchTextFieldView = Em.TextField.extend({
  insertNewline: function() {
    this.get('controller.target').send('showUser', {username: this.get('value')});
  }
});

App.Router = Ember.Router.extend({
  ...
  foo: Ember.Router.extend({
    showUser: function(router, evt) {
      router.transitionTo('displayUserProfile', evt);
    });
  }
});

您应该将 showUser 处理程序放在应用程序中有效的最顶层路由。

这种方法遵循 Ember 应用程序中事件的一般模式,视图处理 DOM 级事件,并在适当的情况下将它们转换为由路由器处理的语义动作。

于 2012-08-31T02:21:45.877 回答
2

我个人认为第二种方法更好。首先,静态访问路由器是个坏主意。然后对我来说,您必须保持视图无逻辑,因此委托给控制器似乎是一个不错的选择。
在您的情况下,这只是对路由器的调用,但您可以想象在文本字段值上处理一些算法。如果您在视图中执行此处理,这将导致视图、混合 UI 代码和逻辑代码。View 应该只处理 UI 代码。

于 2012-08-30T07:11:25.457 回答