EmberJS /选择/内容(列表)/选择/对象平等/比较(比较)

时间:2015-04-30 22:32:42

标签: ember.js selection equality

我有这样的路线:

ConsultasRoute = Em.Route.extend({
  model: function() {
    return Em.Object.create({
      tipoClave: undefined,
      tipoConsulta: {id: 2, nombre: 'yow man'}
    });
  }
});

我有一个像这样的控制器:

ConsultasController = Ember.ObjectController.extend({
  tipoConsultas: [{id: 1, nombre: 'dudeee'}, {id: 2, nombre: 'yow man'}] 
});

这样的模板:

{{view 'select' content=tipoConsultas selection=model.tipoConsulta optionValue="content.id" optionLabelPath="content.nombre" prompt="Selecciona tipo consulta"}}

这个想法是:默认情况下,所选择的tipo consulta是" yow man"。

但这不起作用; "哇男人"默认情况下未选中。

我认为对象平等的事情就在这里。如何告诉ember使用对象的特定属性进行对象相等性检查(例如:" id")?

我读到了这个可比较的混音:http://emberjs.com/api/classes/Ember.Comparable.html#method_compare也许这可以帮助(?)。但我无法在任何地方找到正确使用的例子。

有人可以告诉我如何解决这个问题吗?

已添加,回复@torazaburo(https://stackoverflow.com/a/29981303/3443096):

实际上我在以前的项目中使用过这种方法。所以我在咨询路线中有类似的东西(为了讨论,让我们使用Consultas的东西,实际上它是其他实体):

ConsultasRoute = Em.Route.extend({
   model: function() {
     return Em.$.ajax({
        url: 'http://myserver/userLatestConsulta?idUsuario=111',
        type: 'POST',
        ...
     }).then(function(responseJSON) {
        return Em.Object.create({
          tipoClave: undefined,
          tipoConsultaId: resposeJSON.latestTipoConsultaId
        });
     });
   }
});

关键是,此会话的初始tipoConsulta是从后端获取的(例如:上一个会话中使用的最新版本)。

初始化我的选择视图的方法类似于您在评论中描述的方法:

ConsultasRoute = Em.Route.extend({
  afterModel: function(consulta, transition) {
    var matchingTipoConsulta = _.find(this.controller.get('tipoConsultas'), function(tc) {
      return tc.id == consulta.tipoConsultaId; 
    });

    consulta.set('tipoConsulta', matchingTipoConsulta);
  }
});

但我觉得......"我不应该写这些代码" ......可能有一种更简洁/优雅的方式来做到这一点。这就是为什么我看着Comparable Mixin ......(可能是因为我的背景是java编程,习惯于覆盖' equals'方法,它通常适用于这样的情况)。我希望能听到这个蠢货"选择"利用那个混合物。是吗?

更新

确认:在这种情况下,Ember不会使用mixin Ember.Comparable。我尝试像这样定义一个Ember.Object:

MyNamespace.TipoConsulta = Em.Object.extend(Em.Comparable, {
  id: undefined,
  nombre: undefined
});

MyNamespace.TipoConsulta.reopenClass({
  compare: function(a, b) {
    console.log('-------------- compare --------------');
    if (a.id == b.id) return 0;
    if (parseInt(a.id) < parseInt(a.id)) return -1;
    return 1;
  }
});

然后,用这种方式重新定义我的目录:

MyNamespace.tipoConsultas = [
  MyNamespace.TipoConsulta.create({id: "1", nombre: "dude"}),
  MyNamespace.TipoConsulta.create({id: "2", nombre: "yow man"})
];

我的模板:

{{view 'select' content=MyNamespace.tipoConsultas selection=model.tipoConsulta optionValue="content.id" optionLabelPath="content.nombre" prompt="Selecciona tipo consulta"}}

我的路线:

MyNamespace.ConsultasRoute = Em.Route.extend({
  model: function() {
    return Em.Object.create({
      tipoClave: null,
      tipoConsulta: MyNamespace.TipoConsulta.create({id: "2", nombre: "yow man"}))
    });
  }
});

观察:

  1. 永远不会调用compare方法(清除指示Ember在这种情况下不使用它。)

  2. 更糟糕的是,ember select视图在某一点上将路由模型的tipoConsulta属性重置为“null”&#39;。 (我猜是因为它无法在tipoConsultas目录列表中找到&#34;匹配&#34;。

  3. 因此:在下拉框中未选中任何内容(默认情况下)。

  4. 但是,如果我改变我的路线:

    MyNamespace.ConsultasRoute = Em.Route.extend({
      model: function() {
        return Em.Object.create({
          tipoClave: null,
          tipoConsulta: MyNamespace.tipoConsultas[1]
        });
      }
    });
    
    1. 不调用compare方法。与上述相同。
    2. 路线模型的tipoConsulta属性无法重置。
    3. &#39;你好男人&#39;默认情况下会在下拉列表中选中。
    4. 我觉得很可惜Ember在这种情况下使用Ember.Comparable mixin进行对象比较。

      祝你好运, 拉嘎

1 个答案:

答案 0 :(得分:2)

是的,这是关于对象的平等。您在路径中的模型中定义的{id: 2, nombre: 'yow man'},并且您在控制器中设置为tipoConsultas的值的数组的词法相同成员不是“相等”。他们只是“相同”。在查找所选项目时,Ember不会进行深入比较。但是,您不必担心以某种方式提供自己的比较功能。您只需要确保最初选择的项 是数组中的一个项目。

根据整体情况,有不同的方法可以解决这个问题,但这是一个示例,在tipoConsulta挂钩中使用setupController中的实际条目初始化tipoConsultas

ConsultasRoute = Em.Route.extend({
  model: function() {
    return Em.Object.create({
      tipoClave: undefined
      // remove tipoConsulta from here
    });
  },

  // Initialize the selected item.
  // Replace firstObject with some other criteria as desired.
  setupController: function(controller, model) {
    controller.set('tipoConsulta', controller.get('tipoConultas.firstObject'));
  }
});

ConsultasController = Ember.ObjectController.extend({
  tipoConsultas: [{id: 1, nombre: 'dudeee'}, {id: 2, nombre: 'yow man'}],            

  // Will be set in setupController.
  tipoConsulta: null 
});