11

Actualmente estoy tratando de poner algo junto con ember + emberdata + router + asp.net web api. La mayor parte parece funcionar, sin embargo, me quedé atrapado en un mensaje de error que recibí cuando ember-data intentó findAll a través del adaptador para mis modelos.Ember-Data: ¿Cómo funcionan las "asignaciones"

En mi backend Tengo un modelo como este (C#):

public class Genre { 
    [Key] 
    public int Id { get; set; } 
    [Required] 
    [StringLength(50, MinimumLength=3)] 
    public string Name { get; set; } 
} 

Que en mi aplicación lo represento como esto utilizando brasa-datos:

App.Genre = DS.Model.extend({ 
    id: DS.attr("number"), 
    name: DS.attr("string") 
}).reopenClass({ 
    url: 'api/genre' 
}); 

que también tienen una tienda define en mi aplicación con la RESTAdapter así:

App.store = DS.Store.create({ 
    revision: 4, 
    adapter: DS.RESTAdapter.create({ 
     bulkCommit: false 
    }) 
}); 

Y la tienda se utiliza en mi controlador de la siguiente manera:

App.GenreController = Ember.ArrayController.extend({ 
    content: App.store.findAll(App.Genre), 
    selectedGenre: null 
}); 

El router se define como

App.router = Em.Router.create({ 
    enableLogging: true, 
    location: 'hash', 
    root: Ember.Route.extend({ 
     //... 

     genre: Em.Route.extend({ 
      route: '/genre', 
      index: Ember.Route.extend({ 
       connectOutlets: function (router, context) { 
        router.get('applicationController').connectOutlet('genre'); 
       } 
      }) 
     }), 

     //... 
    }) 
}) 

Cuando ejecuto mi aplicación, me sale el siguiente mensaje para cada objeto que tiene esta misma estructura:

Uncaught Error: assertion failed: Your server returned a hash with the key 0 but you have no mappings

Como referencia, aquí está el json el servicio está volviendo:

[ 
    { 
    "id": 1, 
    "name": "Action" 
    }, 
    { 
    "id": 2, 
    "name": "Drama" 
    }, 
    { 
    "id": 3, 
    "name": "Comedy" 
    }, 
    { 
    "id": 4, 
    "name": "Romance" 
    } 
] 

No puedo decir exactamente cuál es el problema y dado que la afirmación está mencionando que necesito mapeo, me gustaría saber:

  1. Lo que esta asignación es y la forma de utilizarlo.
  2. Dado que el json devuelto es una matriz, ¿debería utilizar un tipo diferente de controlador en mi aplicación, o hay algo que deba saber al trabajar con este tipo de json en Ember-Data? o debería cambiar las opciones de JsonFormatter en el servidor?

Cualquier ayuda es bienvenida.

Definitivamente puedo agregar más información si cree que esto no es suficiente para entender el problema.

EDITAR: he cambiado algunas cosas en mi backend y ahora mi findAll() acción equivalente en el servidor de la serializa el resultado que el siguiente JSON:

{ 
    "genres": [ 
     { "id": 1, "name": "Action" }, 
     { "id": 2, "name": "Drama" }, 
     { "id": 3, "name": "Comedy" }, 
     { "id": 4, "name": "Romance" } 
    ] 
} 

Pero todavía no puede conseguir que pueblan mis modelos en el cliente y mi mensaje de error ha cambiado a esto:

Uncaught Error: assertion failed: Your server returned a hash with the key genres but you have no mappings

No está seguro de qué otra cosa podría estar haciendo mal.

El método que lanza esta excepción es sideload y comprueba si las asignaciones de esta manera:

sideload: function (store, type, json, root) { 
     var sideloadedType, mappings, loaded = {}; 

     loaded[root] = true; 

     for (var prop in json) { 
      if (!json.hasOwnProperty(prop)) { continue; } 
      if (prop === root) { continue; } 

      sideloadedType = type.typeForAssociation(prop); 

      if (!sideloadedType) { 
       mappings = get(this, 'mappings'); 
       Ember.assert("Your server returned a hash with the key " + prop + " but you have no mappings", !!mappings); 
//... 

Esta llamada sideloadedType = type.typeForAssociation(prop); vuelve undefined y luego me sale el mensaje de error. El método typeForAssociation() comprueba la clave 'associationsByName' que devuelve un Ember.Map vacío.

Todavía no hay solución para esto en este momento.

Por cierto ...

Mi acción es ahora así:

// GET api/genres 
    public object GetGenres() { 
     return new { genres = context.Genres.AsQueryable() }; 
    } 

    // GET api/genres 
    //[Queryable] 
    //public IQueryable<Genre> GetGenres() 
    //{ 
    // return context.Genres.AsQueryable(); 
    //} 

tuve que quitar la implementación original que obtiene serializado por json.NET ya que no pude encontrar config opciones para producir una salida json como espera Ember-Data (como en {resource_name : [json, json,...]}). El efecto secundario de esto es que he perdido el soporte incorporado de OData, pero me gustaría conservarlo. ¿Alguien sabe cómo podría configurarlo para producir json diferente para una colección?

Respuesta

12

El mapeo puede ser definido en el DS.RESTAdapter. Creo que podrías intentar definir algo como esto:

App.Store = DS.Store.extend({ 
    adapter: DS.RESTAdapter.create({ 
    bulkCommit: true, 
    mappings: { 
     genres: App.Genre 
    }, 
    // you can also define plurals, if there is a unregular plural 
    // usually, RESTAdapter simply add a 's' for plurals. 
    // for example at work we have to define something like this 
    plurals: { 
     business_process: 'business_processes' 
     //else it tries to fetch business_processs 
    } 
    }), 
    revision: 4 
}); 

Espero que esto resuelva tu problema.

Actualización:

En este momento, esto no está bien documentada, no me acuerdo si nos encontramos por nosotros mismos la lectura del código, o tal vez Tom Dale señalamos en él.
De todos modos, aquí está el punto para plurals Para las asignaciones, creo que fuimos impulsados ​​por el mismo error que usted, y o bien lo intentamos, o Tom nos enseñó sobre esto.

+0

Ambas respuestas ayudaron, creo que realmente no sabía dónde establecer las asignaciones. Ahora finalmente voy a empezar a trabajar con las vistas y las plantillas. Gracias Sylvain – MilkyWayJoe

+0

Última cosa sobre esto, no he podido encontrar ninguna información específica sobre 'mappings'.¿Podría señalar dónde podría haberlo encontrado? Si solo está en el código fuente? Podría/debería estar disponible en el léame tho. – MilkyWayJoe

+0

De nada :) –

8

El RESTAdapter espera que la volvieron JSON ser de la forma:

{ 
    "genres": [{ 
    "id": 1, 
    "name": "action" 
    },{ 
    "id": 2, 
    "name": "Drama" 
    }] 
} 

Las pruebas son una buena fuente de documentación, ver https://github.com/emberjs/data/blob/master/packages/ember-data/tests/unit/rest_adapter_test.js#L315-329

+0

logré hacer mi servicio para producir JSON en el mismo formato, pero ahora me sale el mensaje "* error no detectada: Error de aserción: El servidor devuelve un hash con los géneros clave pero no tienes mapeos * ". Me las arreglé para cargar con un conjunto diferente de controladores/modelos con ascua 0.9.1 y sin datos de asbesto – MilkyWayJoe

+0

Bueno, desafortunadamente no es el formato json, es otra cosa ahora que estoy devolviendo el formato indicado anteriormente y ahora obtengo el mismo mensaje para otra propiedad y ya no para el índice. – MilkyWayJoe

3

Estoy usando Ember Data rev. 11 y parece que la configuración en DS.RESTAdapter.create nunca funciona. La miré a los códigos y encontré una solución de la siguiente manera:

App.Adapter = DS.RESTAdapter.extend({ 
    bulkCommit: false 
}) 

App.Adapter.configure('plurals', { 
    series: 'series' 
}) 
Cuestiones relacionadas