3

当前情况: 我正在尝试找到一种方法来从组件的“didInsertElement”方法中创建特定模型的记录,并将所述数据添加到数据存储中。

当前情况的原因:我将事件侦听器附加到组件 HBS 文件中的按钮。其中一个按钮将触发两个级联但轻量级的 ajax 调用。最后一次 ajax 调用的响应将决定我是否应该创建记录。

我遇到的问题:当我尝试从组件访问这样的商店时:

var myStore = this.store

我得到一个未定义的对象。对于那些询问的人,我已经在我的组件中添加了以下行:

store: Ember.inject.service()

我已经安装了 Ember-Data。

解决方案:我从大量研究中发现,与商店的互动最好通过主路线进行。但是如何将事件侦听器从路由附加到组件的 jquery 小部件?

是否有任何解决方案不需要我将所有事件侦听器代码从组件移动到路由,从而取消 ember 应该提供的模块化?

4

1 回答 1

7

this.store属性存在于默认注入它的元素(控制器和路由)上,并且可能不应该使用,因为它跳过了 getter,这是 Ember 的重要组成部分。

在组件中访问它的正确方法(假设您注入了它)是通过:

this.get('store')

我从大量研究中发现,与商店的互动最好通过主要途径进行。

您可能希望(至少在大多数情况下)不是在主路由中而是在组件所在的控制器中访问存储数据,然后将数据传递给组件。

这有几个原因:

  • Routes 的主要用途是获取数据并控制应用程序的路由机制,用户转换到的位置,转换发生的时间点以及转换的原因等。Routes 不应该控制显示哪些数据以及如何显示,只是如何/何时显示其获得。
  • 控制器的主要用途是数据按摩、准备、转换等。这包括过滤数据、排序、提取子集等。
  • 控制器数据在模板中直接可用,路由数据不可用。

Ember.Route 中的setupController()钩子实际上默认执行此操作。

这是在钩子中完成的默认操作:setupController()

set(controller, 'model', model);

因此,您的控制器默认可以访问模型,然后可以将其传递给组件。

通过这种方式,您可以清楚地将提取/获取/处理数据的逻辑与显示数据的逻辑分开。

我将事件侦听器附加到我的组件 HBS 文件中的按钮。其中一个按钮将触发两个级联但轻量级的 ajax 调用。最后一次 ajax 调用的响应将决定我是否应该创建记录。

在 Ember 中执行此操作的自然方法是将操作附加到您的按钮,该操作只会传播到控制器

// inside components/example.js
// ...
actions: {
  myButtonAction() {
    // call the controller action
    this.get('controllerActionThatWasPassedIn')(/* pass any data if necessary */);
  }
}

并让控制器执行实际的存储操作,然后在需要时将任何结果传递回组件。

// controllers/example.js
// ...
actions: {
  handleData(someArgs) {
    this.get('store)'.findSomething(someArgs).then((result) => {
      this.set('result', result); // set the result which will automatically be passed down into the component
    });
  }
}

// templates/example.hbs
{{my-component result=result
               controllerActionThatWasPassedIn=(action "handleData")
}}

在 Ember 中,这个概念称为Data down,Actions up

像这样传递的动作被称为闭包动作,事实上,你也可以return从它们那里得到这样的东西:

// inside components/example.js
// ...
actions: {
  myButtonAction() {
    // call the controller action
    this.get('controllerActionThatWasPassedIn')(/* pass any data if necessary */)
      .then((result) => {
        // do stuff with result
      });
  }
}

如何将事件侦听器从路由附加到组件的 jquery 小部件?

注意:反模式

在 Ember 中并没有真正的自然方式来执行此操作,主要是因为路由和控制器是在渲染之前创建的。这就是为什么您不想在 Route 和 Controller 中执行此操作。

但是,如果您可能不需要 Controller 并且只想在 Route 中执行一些快速/小型 DOM 操作(请注意,这通常是一种反模式),您可以随时使用Ember Run Loop挂钩并安排一些操作在渲染之后发生:

export default Ember.Route.extend({
  init() {
    this._super(...arguments);

    Ember.run.scheduleOnce('afterRender', () => {
      $('.my-component').click(/* ... */)
    });
  }
});

或者您可以在渲染内容后直接在renderTemplate()挂钩中执行此操作:

renderTemplate() {
  this.render();
  $('.my-component').click(/* ... */); // Probably shouldn't do this though
}
于 2016-09-07T15:43:15.870 回答