【问题标题】:Ember: When child controllers are observing same property of Parent controller firing request simultaneouslyEmber:当子控制器同时观察父控制器触发请求的相同属性时
【发布时间】:2015-03-31 10:28:07
【问题描述】:

我创建了一个包含两个子对象控制器和一个父数组控制器的应用程序。路线也以同样的方式描述。

var App = Ember.Application.create({
  LOG_TRANSITIONS: true
});

App.Router.extend(function() {
  this.resource('parent', function() {
    this.route('child1', {
      path: '/'
    });
    this.route('child2');
  });
});

var ParenteRoute = Ember.Route.extend({
  model: function() {
    //Got my model from here.
  };
});

var Child1Route = Ember.Route.extend({
  model: function(){
    return Ember.$.ajax('dummyUrl.com');
  },
  action:{
    refreshData: function(){
      var controller = this.controllerFor('parent.child1');
      return Ember.$.ajax('dummyUrl.com').then(function(response){
        return controller.send('updateModel' response);
      });
    }
  }
});

var ParentController = Ember.ArrayController.extend({
  getFirstName: function() {
    return this.get('model').get('firstName');
  },
  getLastName: function() {
    return this.get('model').get('lastName');
  }
});

var Child1Controller = Ember.ObjectController.extend({
  needs: ['ParentController'],
  getName: function() {
    return this.get('controllers.ParentController.getFirstName')
  },
  updateName: function() {
    this.send('refreshData');
  }.observes('controllers.ParentController.getLastName'),
  actions: {
    updateModel: function(response) {
      this.set('getName', response);
    }
  }
});

var Child2Controller = Ember.ObjectController.extend({
  needs: ['ParentController'],
  getFirstName: Ember.computed.alias('controllers.ParentController.getFirstName')
});
<!--Parent Template--!>
<div>
<input type='text' {{bind-attr value=getFirstName}}>
<input type='text' {{bind-attr value=getLastName}}>
</div>
{{#link-to 'parent.child1'}}child1{{/link-to}}
{{#link-to 'parent.child2'}}child2{{/link-to}}
{{outlet}}

<!--child1 template--!>

<div>
  {{getName}}
</div>

<!--child2 template--!>

<div>
  {{getFirstName}}
</div>

所以上面代码的问题是,当我在父控制器的索引中时,每次调用 child1 的函数 updateName() 并正确执行时都会更改 getLastName 属性。但是,如果通过单击链接移动到 child2 的路由,则在保持 child1 路由活动的同时进行一些更改后,然后当我更改属性 getLastName 时,虽然我在 child2 中,但由于观察到,child1 的 updateName() 函数也被触发函数并抛出错误:

    Uncaught Error: Nothing handled the action 'refreshData'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.

我需要帮助来了解如何解决这个问题。并且这种在父控制器的属性发生变化时重新加载子模型的方法是否是一个好方法,如果不是那么请提出正确的方法。

【问题讨论】:

  • 你到底想完成什么?
  • 首先,当我在 child1 路线中时,我尝试根据父项的 getLastName 属性中所做的更改来刷新或重新加载我的模型。在第二个中,我只是显示父级的 getFirstName 属性。但是当我从 Child1 路由移动到 child2 路由时,即使我在 child2 路由中也会调用 refreshData 方法,这会引发未处理的操作错误,我相信这是对在 refreshData 方法上设置观察者进行的操作。
  • 我基本上不希望观察者在我处于不同的子路由时触发。

标签: javascript ember.js ember-cli


【解决方案1】:

好的,所以您希望属性在不同的模板中更新。您需要尝试从管理对象(模型)而不是这些对象的属性的角度来考虑 Ember。使用 Ember 的绑定,属性应该会自动更新。您需要考虑使用 store 来管理所述对象。

你在ParentController 中什么都不是。您可以直接在模板中使用来自ParentRoute 的模型,例如

<div>
  {{input value=model.firstName}}
  {{input value=model.lastname}}
</div>
{{#link-to 'parent.child1'}}child1{{/link-to}}
{{#link-to 'parent.child2'}}child2{{/link-to}}
{{outlet}}

然后您的子控制器变得更加简单:

App.Child1Controller = Ember.ObjectController.extend({
  needs: ['ParentController'],
  parentModel: Ember.computed.alias('controllers.ParentController.model')
});

App.Child2Controller = Ember.ObjectController.extend({
  needs: ['ParentController'],
  parentModel: Ember.computed.alias('controllers.ParentController.model')

});

你会像这样在你的模板中使用它们:

<div>
  {{parentModel.firstName}}
</div>

【讨论】:

  • 我明白你的意思,但我需要在第一个孩子的父控制器属性的 lastName 更改时通过服务调用刷新并获取完全不同的数据。所以我想出了那个代码。所以只有我在 child1 控制器的 updateName 方法上设置了观察者。但是当我移动到 Child 2 控制器时,我不想要那种情况。我确实知道由于 Ember 在 updateName 方法上的观察者标记,无论它是否是活动路线,它都会被触发,我想知道是否有任何其他方法可以避免它并在 Ember 中获得我想要的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
相关资源
最近更新 更多