2013-07-04 4 views
2

Я пытаюсь написать довольно простое приложение: у меня есть некоторые игры (например, шахматы, тиктак ... что угодно), и есть несколько советов каждой игры. Я хочу показать список игр, а затем показать список досок, когда вы нажмете на игру.Загрузка одной модели с Ember.js

Но у меня много проблем. Сначала я опишу их, и я буду вставлять код после этого:

  1. Список игр показан правильно. Здесь нет проблем.
  2. Когда я нажимаю игру, я получаю эту ошибку:

    Uncaught Error: assertion failed: an Ember.CollectionView's content must implement Ember.Array. You passed <(generated game controller):ember237>

    НО если нажать клавишу F5 или написать URL вручную, все работает отлично. И я понятия не имею, почему.

    UPDATE: Я видел, что если изменить games шаблон, изменив {{#linkTo}} со ссылкой рукописной, все работает нормально:

    • Это нерабочий linkTo: {{#linkTo 'game' game}}{{game.name}}{{/linkTo}}. Он правильно строит URL-адрес, но он терпит неудачу, когда я нажимаю на него.
    • Это рукописный текст: <a> тег: <a href="#/games/{{unbound game.id}}">{{game.name}}</a>. Он работает отлично.
  3. адреса URL каждого совета должен иметь следующий формат:

    /games/1/boards/5

    Но когда я пишу {{#linkTo 'board' board}} то, что я получаю:

    /games/undefined/boards/5

Здесь это код (вы можете увидеть «рабочую» копию here in JBin. Но это не работает, потому что он ретранслирует на локальном приложении REST):

Маршрутизатор:

MGames.Router.map(function() { 
    this.resource('games', function() { 
     this.resource ('game', {path: '/:game_id'}, function() { 
      this.resource('board', {path: '/boards/:board_id'}); 
     }); 
    }); 
}); 

MGames.IndexRoute = Ember.Route.extend({ 
    redirect: function() { 
     this.transitionTo('games'); 
    } 
}); 

MGames.GamesRoute = Ember.Route.extend ({ 
    model: function() { 
     return MGames.Game.findAll(); 
    } 
}); 

MGames.GameRoute = Ember.Route.extend ({ 
    model: function(params) { 
     return MGames.Board.findAllByGame(params.game_id); 
    } 
}); 

MGames.BoardsRoute = Ember.Route.extend ({ 
    model: function(params) { 
     return this.modelFor('game').then(
      function (game) { 
       return MGames.Board.find(game.get('id'), params.board_id); 
      } 
     ); 
    } 
}); 

Модели:

MGames.Game = Ember.Object.extend({ 
    id: null, 
    name: null, 
    icon: null 
}); 

MGames.Game.reopenClass({ 
    findAll: function() { 
     var url = [MGames.GAMES_API_URL]; 
     url.push ('games'); 
     url = url.join('/'); 

     var result = Ember.ArrayProxy.create({ content: [] }); 

     $.getJSON(url).then (
      function (response) { 
       response.forEach(function (child) { 
        result.pushObject (MGames.Game.create(child)); 
       }); 
      } 
     ); 

     return result; 
    }, 

    find: function (id) { 
     var url = [MGames.GAMES_API_URL]; 
     url.push ('games'); 
     url.push (id); 
     url = url.join('/'); 

     var game = MGames.Game.create({ isLoaded: false }); 

     $.getJSON(url).then (
      function(response) { 
       game.setProperties(response); 
       game.set('isLoaded', true); 
      } 
     ); 

     return game; 
    } 
}); 

MGames.Board = Ember.Object.extend({ 
    id: null, 
    name: null, 
    owner: null, 
    game: null, 
    is_public: null, 
    created_at: null 
}); 

MGames.Board.reopenClass({ 
    findAllByGame: function (game) { 
     var url = [MGames.GAMES_API_URL]; 
     url.push ('games'); 
     url.push (game); 
     url.push ('boards'); 
     url = url.join('/'); 

     var result = Ember.ArrayProxy.create({ content: [] }); 

     $.getJSON(url).then (
      function (response) { 
       console.log (response); 
       response.forEach(function (child) { 
        result.pushObject (MGames.Board.create(child)); 
       }); 
      } 
     ); 

     return result; 
    }, 

    find: function (game, board) { 
     url = [MGames.GAMES_API_URL]; 
     url.push ('games'); 
     url.push (game); 
     url.push ('boards'); 
     url.push (board); 
     url = url.join('/'); 

     var result = MGames.Board.create(); 

     $.getJSON(url).then (
      function(response) { 
       result.setProperties(response); 
      } 
     ); 

     return result; 
    } 
}); 

И шаблон:

<!doctype html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title>MGames</title> 
    <link rel="stylesheet" href="css/bootstrap.css"> 
    <link rel="stylesheet" href="css/main.css"> 
</head> 
<body> 

    <script type="text/x-handlebars"> 
    <div class="navbar navbar-fixed-top"> 
     <div class="navbar-inner"> 
     <div class="container"> 
      <div class="nav-collapse collapse"> 
      <ul class="nav"> 
       <li class="active">{{#linkTo 'index' class="brand"}}MGames{{/linkTo}}</li> 
      </ul> 
      </div> 
     </div> 
     </div> 
    </div> 

    <div class="container"> 
     {{outlet}} 
    </div> 
    </script> 

    <script type="text/x-handlebars" id="games"> 
    <div class="row"> 
     <header id="header"> 
     <h1>Games</h1> 
     </header> 
     <ul> 
     {{#each game in controller}} 
     <li> 
     {{#linkTo 'game' game}}{{game.name}}{{/linkTo}} 
     </li> 
     {{/each}} 
     </ul> 

     {{outlet}} 
    </div> 
    </script> 

    <script type="text/x-handlebars" id="game"> 
    <div class="row"> 
     <div class="span3" id="boards"> 
     <header id="header"> 
      <h1>Boards</h1> 
     </header> 

     <ul id="board-list"> 
      {{#each board in controller}} 
      <li> 
      {{#linkTo 'board' board}}{{board.name}}{{/linkTo}} 
      </li> 
      {{/each}} 
     </ul> 
     </div> 
     <div class="span9"> 
     {{outlet}} 
     </div> 
    </div> 
    </script> 

    <script type="text/x-handlebars" id="board"> 
    <header id="header"> 
     <h1>{{game.name}} - {{name}} <small>{{owner.nickname}}</small></h1> 
    </header> 
    </script> 

    <script src="js/libs/jquery.js"></script> 
    <script src="js/libs/bootstrap.js"></script> 
    <script src="js/libs/handlebars.js"></script> 
    <script src="js/libs/ember.js"></script> 

    <script src="js/application.js"></script> 
    <script src="js/router.js"></script> 
    <script src="js/models/game.js"></script> 
    <script src="js/models/user.js"></script> 
</body> 
</html> 

ответ

4

Хорошо, я, наконец, понял проблему.В моем gameRoute я писал:

MGames.GameRoute = Ember.Route.extend ({ 
    model: function(params) { 
     return MGames.Board.findAllByGame(params.game_id); 
    } 
}); 

Он работал, когда я пишу URL непосредственно в строке браузера, поскольку Эмбер вызывает функцию model, но когда после {{#linkTo}} модель является один передается в качестве параметра, поэтому model функция не называется.

Так что рабочий код это один (немного упрощенным):

MGames.GameRoute = Ember.Route.extend ({ 
    model: function (params) { 
     // This is only called when loading the URL directly, 
     // not following a link. We load the game, and in the 
     // setupController we'll load the boards. 
     return MGames.Game.find(params.game_id); 
    }, 
    setupController: function(controller, game) { 
     // This is *always* called, so we load the boards 
     model = MGames.Board.findAllByGame(game.id); 
     controller.set('model', model); 
    } 
}); 
2

В маршруте board, на который вы ссылаетесь, есть 2 динамических сегмента, но вы предоставляете только один. Вам нужно изменить, чтобы,

{{#linkTo 'board' game board}}The board{{/linkTo}} 

Ошибка undefined, вероятно, из-за ArrayController не получают плату, как соответствующая игра идентификатор передается в undefined. Вышеизложенное изменение также должно исправить это.

+0

Я изменил эту линию с этим, и теперь он работает, спасибо !: '{{#linkTo ' board ".} Совет {{/ linkTo}}' В любом случае самая большая проблема - проблема с номером 2: когда я нажимаю на игру. Я бы очень признателен за anser :-) –

Смежные вопросы