使用Ember.js加载单个模型
Loading a single model with Ember.js
我正在尝试编写一个非常简单的应用程序:我有一些游戏(比如国际象棋、tictactoe…等等),每个游戏都有几个棋盘。我想显示游戏列表,然后在你点击游戏时显示棋盘列表。
但我面临着很多问题。我将首先描述它们,然后粘贴代码:
- 游戏列表显示正确。这里没问题
-
当我点击一个游戏时,我会得到这个错误:
Uncaught Error: assertion failed: an Ember.CollectionView's content must implement Ember.Array. You passed <(generated game controller):ember237>
但是,如果我按F5键或手动编写URL,一切都很好。我不知道为什么。
UPDATE:我已经看到,如果我更改
games
模板,用手写链接更改{{#linkTo}}
,一切都正常:- 这是不工作的链接To:
{{#linkTo 'game' game}}{{game.name}}{{/linkTo}}
。它正确地构建了URL,但当我点击它时它失败了 - 这是一个手写的
<a>
标签:<a href="#/games/{{unbound game.id}}">{{game.name}}</a>
。它工作得很好
- 这是不工作的链接To:
-
每个板的Url应遵循以下格式:
/games/1/boards/5
但当我写
{{#linkTo 'board' board}}
时,我得到的是:/games/undefined/boards/5
以下是代码(您可以在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>
好的,我终于解决了这个问题。在我的gameRoute
中,我写道:
MGames.GameRoute = Ember.Route.extend ({
model: function(params) {
return MGames.Board.findAllByGame(params.game_id);
}
});
当我直接在浏览器栏中编写URL时,它就起作用了,因为Ember调用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);
}
});
您链接到的board
路由有2个动态段,但您只提供了一个。您需要更改为,
{{#linkTo 'board' game board}}The board{{/linkTo}}
undefined
错误可能是由于ArrayController
没有得到棋盘,因为相应的游戏id被传递为undefined
。上述变化也应该解决这个问题。
- 引用单个表的多列 - Sails JS API 模型
- Ember.js:如何使用模型的单个实例创建路由/控制器
- 主干:在单个请求中批量保存模型
- 如何阻止单个模型将其 id 添加到 Backbone 中的 url
- 使用单个模型编辑多个变量
- 使用单个 ng 模型筛选结果并显示筛选方法
- KnockoutJS与jQuery数据表和绑定插件,行单击传递整个数组而不是单个模型
- Knockoutjs:如何将单个项目从可观察数组传递到我的视图模型中
- Extjs使用复选框模型在网格上拖放单个项目
- ng模型不会为文本过滤器重新计算单个按键的数组长度
- 使用Ember.js加载单个模型
- 在主干网中获取单个模型,为什么不't这项工作
- BackboneJS:从不同的视图修改单个模型
- AngularJS获取单个模型记录用于在模态中编辑
- js不能获取单个模型
- Ember.ArrayController's数组模型中单个模型的观察者
- 是否有可能在MVC中禁用单个模型属性的客户端验证?
- React + Flux——将输入绑定到单个“模型”的嵌套组件
- 如何淡入/淡出单个模型时,$scope.items在Angular JS中被更新
- 骨干收集获取单个模型