在模型初始化中设置的Backbone.js不影响集合中的模型



在对主干集合执行fetch()并将模型实例化为该集合的子模型时,我想为每个模型添加更多的信息。

我认为我可以在模型初始化中使用set来做到这一点。(我的假设是fetch()正在为传入它的每个对象实例化一个新模型。因此,当每次初始化发生时,额外的数据片段将被设置。

为了说明我的问题,我粘贴了四个片段,第一个来自我的集合类。其次是模型类中的初始化函数。第三,我在初始化函数中使用两个函数来从flickr api获取所需的信息。第四,也是最后,执行fetch() .

的app.js。第一个集合类:
var ArmorApp = ArmorApp || {};
ArmorApp.ArmorCollection = Backbone.Collection.extend({
    model: ArmorApp.singleArmor,
    url: "https://spreadsheets.google.com/feeds/list/1SjHIBLTFb1XrlrpHxZ4SLE9lEJf4NyDVnKnbVejlL4w/1/public/values?alt=json",
  //comparator: "Century",
  parse: function(data){
    var armorarray = [];
    var entryarray = data.feed.entry;
    for (var x in entryarray){
        armorarray.push({"id": entryarray[x].gsx$id.$t,
                          "Filename": entryarray[x].gsx$filename.$t, 
                          "Century": entryarray[x].gsx$century.$t,
                          "Date": entryarray[x].gsx$date.$t,
                          "Country": entryarray[x].gsx$country.$t,
                          "City": entryarray[x].gsx$city.$t,
                          "Type": entryarray[x].gsx$type.$t,
                          "Maker": entryarray[x].gsx$maker.$t,
                          "Recepient": entryarray[x].gsx$recipient.$t,
                          "Flickrid": entryarray[x].gsx$flickrid.$t,
                          "FlickrUrl": "", //entryarray[x].gsx$flickrurl.$t,
                          "FlickrUrlBig": ""//entryarray[x].gsx$flickrurlbig.$t,
                        });
      }
      return armorarray;
  }
});

第二,我的模型的初始化。

initialize: function(){
        //console.log("A model instance named " + this.get("Filename"));
        item = this;
        var flickrapi = "https://api.flickr.com/services/rest/?&method=flickr.photos.getSizes&api_key=<my_apikey>&photo_id=" + this.get("Flickrid") + "&format=json&jsoncallback=?"; 
        sources = getFlickrSources(flickrapi);
        sources.then(function(data){
            sourceArray = parseFlickrResponse(data);
            FlickrSmall = sourceArray[0].FlickrSmall;
            console.log (FlickrSmall);
            item.set("FlickrUrl", FlickrSmall);
            console.log(item);
        });

请注意这里我是如何获得"Flickrid"的,并使用它来获得更多的信息,然后试图将它添加回模型与item.set("FlickrUrl", FlickerSmall);

console.log确认属性"FlickrUrl"已设置为所需值。

第三,这些是我的模型用来获取闪烁api所需信息的函数。

var getFlickrSources = function(flickrapi){
  flickrResponse = $.ajax({
      url: flickrapi,
      // The name of the callback parameter, as specified by the YQL service
      jsonp: "callback",
      // Tell jQuery we're expecting JSONP
      dataType: "jsonp"})
  return flickrResponse;
}
var parseFlickrResponse = function(data){
  flickrSourceArray = []
  if (data.stat == "ok"){
    sizeArray = data.sizes.size;
    for (var y in sizeArray){
      if (sizeArray[y].label == "Small"){
        flickrSourceArray.push({"FlickrSmall": sizeArray[y].source});
      }
      else if (sizeArray[y].label == "Large"){
        flickrSourceArray.push({"FlickrLarge": sizeArray[y].source});
      }
    }
  }
  return flickrSourceArray
}

但是,第四,当我尝试执行fetch和渲染集合时,我只获得集合中没有FlickrUrl属性集的对象。

//create an array of models and then pass them in collection creation method
var armorGroup = new ArmorApp.ArmorCollection();
armorGroup.fetch().then(function(){
  console.log(armorGroup.toJSON());
  var armorGroupView = new ArmorApp.allArmorView({collection: armorGroup});
  $("#allArmor").html(armorGroupView.render().el);
});
var armorRouter = new ArmorApp.Router();
Backbone.history.start();

最后一个代码片段中的console.log打印出所有通过fetch实例化的对象/模型。但是它们都不包括初始化时应该是set的额外属性。

知道发生了什么事吗?

这个函数是什么?getFlickrSources (flickrapi)

你为什么要用这个?进入初始化函数。老实说,对于你想做的事情来说,这看起来太复杂了。

如果你想在实例化模型时设置一些参数,那么执行 var model = new model ({param:"someparam", url:"someurl",wtv:"somewtv"});

如果要点是更新你的模型,只需在你的模型中写一个更新函数,如update: function (newparam) {this.set;…等,并在需要时调用。

如果我没看错的话,你只是想在你的模型实例化时设置一些参数,所以就使用我上面指定的。这里有更多的文档:http://backbonejs.org/#Model-constructor

我希望它有帮助。

编辑:

把你的调用放在你的模型之外,你不应该(在我看来)这样在你的模型内部调用,看起来有点脏。

Sources.then(function(flickrdata) {
    var mymodel = new Model({flicker:flickrdata.wtv});
});