断言失败:提供给 set 的键必须是字符串

Assertion Failed: The key provided to set must be a string

我有一个 {{link-to}} 将 ID 传递给 detailhes.js 路由。这条路线 findRecord 我的模型传递了 {{link-to}} ID。有效负载加载所有数据,但是当页面完成加载时出现错误。 我没有找到 "key" 并且我没有 pokemon.detalhes 控制器。 Ember2.18.1

Error: Assertion Failed: The key provided to set must be a string, you passed (generated pokemon.detalhes controller).

我的代码: adapter.js

import DS from 'ember-data';
import { computed } from '@ember/object';

export default DS.RESTAdapter.extend({

    host: 'http://127.0.0.1:8000',
    namespace: 'api/v2',
    headers: computed(function () {
        return {
            'accept': 'application/json'
        };
    }),

    pathForType(type) {
        return type;
    },
/*
    query(store, b, query) {
        store.serializerFor('pokemon').set('pageSize', query.limit);
        const url = `${this.get('host')}/${this.get('namespace')}/pokemon`;
        console.log(url);
        return this.ajax(url, 'GET', {data: query});
    },
*/
    updateRecord(store, type, snapshot) {
        const data = snapshot.record.serialize();
        const headers = Object.assign({}, this.get('headers'), { "pokemon-edit": true });
        const url = this.buildURL(type.modelName, snapshot.id, snapshot, 'updateRecord');
        return this.ajax(url, 'PUT', { headers, data });
    }
});

serializer.js

import DS from 'ember-data';
import _ from 'lodash';

export default DS.RESTSerializer.extend({

normalizeResponse(store, primaryModelClass, payload) {
  debugger  
  return  {
        meta: {
          count: payload.count,
          previous: payload.previous,
          next: payload.next 
        },

        data: 
            payload.results && _.map(payload.results, item => {
              return {
                id: (/.+\/([0-9]+)\//.exec(item.url) || [])[1] || 0,
                type: 'pokemon',
                attributes: item
              }
            }) || {
                    type: 'pokemon',
                    id: payload.id,
                    attributes: Object.assign(payload) 
                  }
    };
  },
});

route/index.js

import Route from '@ember/routing/route';

export default Route.extend({
    model(){
        return this.store.query('pokemon', {limit: 2});
    }
});

index.hbs

<table class="table table-striped">
    <thead class="thead-dark">
        <tr>
        <th scope="col">Id</th>
        <th scope="col">Pokemon</th>
        <th scope="col">Ações</th>
        </tr>
    </thead>
    <tbody>
        {{#each model as |poke|}}
            <tr>
                <th scope="row">{{poke.id}}</th>
                <td>{{sentence poke.name}}</td>
                <td>{{#link-to "pokemon.detalhes" poke.id}}<p class="btn btn-success">Detalhes</p>{{/link-to}}</td>
            </tr>
        {{/each}}

    </tbody>
</table>

来自索引路由的负载数据

{…}
count: 949
next: "http://127.0.0.1:8000/api/v2/pokemon/?limit=2&offset=2"
previous: null
results: […]
0: {…}
  name: "bulbasaur"
  url: "http://127.0.0.1:8000/api/v2/pokemon/1/"
1: {…}
  name: "ivysaur"
  url: "http://127.0.0.1:8000/api/v2/pokemon/2/"
length: 2

route/pokemon/detalhes.js

import Route from '@ember/routing/route';

export default Route.extend({
    model(params) {
        return { params };
    },

    setupController(controller, model) {
        this.store.findRecord('pokemon', model.params.id).then(response => {
            this.set(controller, 'model', response);
            return response;
        })
    }
});

pokemon/detalhes.hbs

<div class="card" style="width: 20rem;">
    <img class="card-img-top" src={{model.image}} alt="Card image cap">
        <div class="card-body">
        <form>
            <div class="form-group">
                <span class="alert-primary">Pokemon:</span>
                <span class="form-control">{{model.name}}</span>
            </div>
            <div class="form-group">
                <span class="alert-primary">XP Base:</span>
                <span class="form-control">{{model.height}}</span>
            </div>
            <button type="submit" class="btn btn-primary">Submit</button>
        </form>  
        </div>
</div>

model/pokemon.js

import DS from 'ember-data';
import { computed, get } from '@ember/object';

export default DS.Model.extend({

    name: DS.attr('string'),
    url: DS.attr(),
    height: DS.attr('number'),
    weight: DS.attr('number'),
    base_experience: DS.attr('number'),
    sprites: DS.attr(),

    image: computed('sprites', function(){
        const img = get('sprites');
        return img.get('sprites.front_default');
    })
});

来自 id=1 的详细路线的负载数据

{…}
abilities: Array [ {…}, {…} ]
base_experience: 64
forms: Array [ {…} ]
game_indices: Array [ {…}, {…}, {…}, … ]
height: 7
held_items: Array []
id: 1
is_default: true
location_area_encounters: "/api/v2/pokemon/1/encounters"
moves: Array [ {…}, {…}, {…}, … ]
name: "bulbasaur"
order: 1
species: Object { url: "http://127.0.0.1:8000/api/v2/pokemon-species/1/", name: "bulbasaur" }
sprites: Object { back_default: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png", back_shiny: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png", front_default: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png", … }
stats: Array [ {…}, {…}, {…}, … ]
types: Array [ {…}, {…} ]
weight: 69

router.js

import EmberRouter from '@ember/routing/router';
import config from './config/environment';

const Router = EmberRouter.extend({
  location: config.locationType,
  rootURL: config.rootURL
});

Router.map(function() {
  this.route('pokemon', function() {
    this.route('edit');
    this.route('edit', { path: 'edit/:id' });
    this.route('detalhes');
    this.route('detalhes', { path: 'detalhes/:id' })
  });
});

export default Router;

您没有控制器 "pokemon.detalhes",但您正在尝试转换到路由 "pokemon.detalhes",因此 Ember 自动为您创建了该控制器。但正如我从您的代码中看到的那样,您有路线 "pokemon.details"。所以尝试使用这个:

<td>{{#link-to "pokemon.details" poke.id}}<p class="btn btn-success">Details</p>{{/link-to}}</td>

如果这不正确,请与我们分享您的 router.js 代码,以便我们更好地了解。

我发现了问题,是 setupController。
我重写了 detalhes 路由器并且工作正常!!

route/pokemon/detalhes.js

export default Route.extend({
    model(params) {
        return this.store.findRecord('pokemon', params.id)
    }
});