如何在Backbone中获取单个模型?


93

Clock在Backbone中有一个模型:

var Clock = Backbone.Model.extend({});

我正在尝试从中获取具有最新信息的实例/clocks/123。我尝试过的一些事情:

“类”级别的方法

Clock.fetch(123)
// TypeError: Object function (){ ... } has no method 'fetch'

创建一个实例,然后调用fetch它:

c = new Clock({id: 123})
c.fetch()
// Error: A 'url' property or function must be specified

集合

我尝试创建一个AllClocks集合资源(即使我在页面上没有用到这种东西):

var AllClocks = Backbone.Collection.extend({
  model: Clock,
  url: '/clocks/'
});
var allClocks = new AllClocks();
allClocks.fetch(123);
// returns everything from /clocks/

如何获得一个 API支持的时钟?


恕我直言,它属于集合。类似于Collection#fetchOne(id,callback)。
朱利安·迈彻

Answers:


26

您的第二种方法是我使用的方法。尝试将以下内容添加到您的Clock模型中:

url : function() {
  var base = 'clocks';
  if (this.isNew()) return base;
  return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + this.id;
},

这种方法假定您已经实现了URL中带有hashbang的控制器,例如http://www.mydomain.com/#clocks/123,但是即使您还没有,它也应该可以工作。



@makevoid您无法使用在咖啡脚本中提供的示例或在文档中提供的示例,Andrew示例有效,可以通过foo.url()提供示例,它总是告诉我没有函数url。
罗伯托·阿拉尔孔

@makevoid似乎只有在模型是在集合中创建的情况下,您引用的方法才有效。请注意中的集合[collection.url]/[id]
Steven Devijver 2014年

@makevoid您能否提供一个有效的链接?不幸的是,这个现在已经坏了
AlexNikolaev94 '16

这是工作链接(他们将文档移动了!哇,已经过去5年了, 真是太好了): 骨架 js.org/#Model-url-@StevenDevijver是正确的
避免

137

尝试在模型中指定urlRoot

从文档:

var Book = Backbone.Model.extend({urlRoot : '/books'});
var solaris = new Book({id: "1083-lem-solaris"});
solaris.fetch();

2
这很好,但是有时您不想重新实例化模型。如果要针对同一模型获取特定项目,则可以进行静默设置:currentBook.set('id', 13423, {silent:true})。这也currentBook.id = 13423
可行

1
之所以起作用,是因为@SimplGy model.id实际上是的同义词model.attributes.id。如果您致电model.set('id'),骨干网将设置model.id为您指定的任何内容。并且model.id是创建特定于模型的URL时使用的内容。
Lambart 2015年

26

我个人建议遵循Model#url方法文档

model = new Model(id: 1)
view = new View(model: model) 
collection = new Collection([model])
model.fetch()

在您的收藏夹中,记得添加收藏夹网址:

url: "/models"

然后在您的View的initialize函数中执行以下操作:

this.model.bind("change", this.render)

这样,骨干网将使用以下网址执行ajax请求:

"/models/1"

您的模型将被更新并呈现视图,而无需修改Collection#url或Model#urlRoot

注意:对不起,这个示例是在coffee脚本中出现的,但是您可以通过添加var语句轻松地将其转换为js


显然这是行不通的。在模型(也不是集合)中调用抓取时,甚至都不会调用服务器
Ricardo Amores 2012年

这看起来不错,但是在我们真的不需要收集的情况下,收集行看起来很尴尬。
2013年

我无法使它工作:this.model.get('field')。看起来模型是被创建的子对象
Muhaimin 2014年

1
this.model.bind(“ change”,this.render,this)对我来说效果很好
dmi3y

1
@UlysseBN是(已于2011年年),您可以添加VAR语句,{}里面()的对于传递的对象和可选的;广告线路末端
makevoid

12
var Person = Backbone.Model.extend({urlRoot : '/person/details'});
var myName = new Person({id: "12345"});
myName.fetch();

结果,您在上发出了Ajax请求

URL http://[domainName]/person/details/id 

并返回了JSON响应。

恩!


2
这是与@Hernan相同的解决方案
Brenden

0

...如果不希望在模型urlRoot上添加斜杠,请执行以下操作:

    url : function() {                        
        return this.urlRoot + this.id;
    },

0

您可能应该通过一个集合访问该对象,并将其始终保持在该集合中。这是怎么做的:

var AllClocks = Backbone.Collection.extend({
  model: Clock,
  url: '/clocks/'
});

var allClocks = new AllClocks();
my_clock = allClocks.add({id: 123});
my_clock.fetch()

2
你不知道 也许他只需要一个时钟。假设我要为客户提供一个单一的用户记录模型?他是否也应该可以访问所有用户的集合?有时人们在尝试保持用例私密时只需要一些建议即可。只是回答。
Adrian Bartholomew 2015年

0

我想使用RESTful网址,但我不明白为什么无法将'postId'添加到基本网址中。

var PostModel = Backbone.Model.extend({
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});

var post = new PostModel({
            postId: 1
        });
alert(post.url());

然后我才知道在Model中将'idAttribute'设置为'postId'后,我才能获得正确的网址。像这样:

var PostModel = Backbone.Model.extend({
    idAttribute: 'postId',
    urlRoot: 'getBlogPost',
    defaults: {
        postTitle: "defaultTitle",
        postTime: "1970-01-01",
        postContent: "defaultContent",
        postAuthor: "anonymous"
    }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.