Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:使用主干构建图像库_Javascript_Backbone.js_Gallery_Image Gallery - Fatal编程技术网

Javascript:使用主干构建图像库

Javascript:使用主干构建图像库,javascript,backbone.js,gallery,image-gallery,Javascript,Backbone.js,Gallery,Image Gallery,我正在用主干网建立一个图像库。用户一次只能查看一个图像,当他使用箭头键导航下一个/上一个图像时,他将看到集合中的下一个图像 我有一个顶级主干视图称为gallery view GalleryView = Backbone.View.extend({ initialize: function(options) { this.collection = PhotosCollection(); } }); 然后,我将为每个图像创建一个视图 PhotoView = Back

我正在用主干网建立一个图像库。用户一次只能查看一个图像,当他使用箭头键导航下一个/上一个图像时,他将看到集合中的下一个图像

我有一个顶级主干视图称为gallery view

GalleryView = Backbone.View.extend({
    initialize: function(options) {
        this.collection = PhotosCollection();
    }
});
然后,我将为每个图像创建一个视图

PhotoView = Backbone.View.extend
我将跟踪视图中集合中的当前模型,并为该模型创建photoView

我的问题是关于分页或预取不在视图中的图像。我不确定galleryView如何能够保存多个照片视图,然后显示聚焦的一个。我正在考虑为整个收藏创建一个长div,然后在索引位置为每张照片添加div。从该分区添加或删除新图像的策略是什么

我不确定galleryView如何能够保存多个照片视图,然后显示聚焦的一个

这是最简单的部分。只要视图没有附加到DOM,它就保持不可见,您可以引用任意多个视图,并且在任何时候只附加其中一个视图

我正在考虑为整个收藏创建一个长div,然后在索引位置为每张照片添加div。从该分区添加或删除新图像的策略是什么


让每个图片都有一个UL和一个LI,不管怎样,如果你想预加载图像,我想下一个就足够了,你不需要删除照片视图,只要它们不是数量不合理的照片,只需将它们从视图中滚出或隐藏,如果你真的想删除视图,请调用remove().

更新

我已经修改了我的原始代码。虽然这显然是未经测试,但它应该给你一个合理的开始。一旦创建了
img
元素并且设置了
src
属性(),图像就开始预加载。它们不必附加到DOM。我在下面介绍的这个改进版本将基于
paginationPadding
变量预加载当前图像前后的图像

结束更新

在主干网中处理内容时,将所有与状态相关的信息保留在模型中,然后让UI响应这些信息,这会有所帮助。在这种情况下,只需跟踪要在模型中显示的图像,然后响应模型中的更改跟踪要查看的照片,只需重新渲染照片库即可显示所需的图像。它是反应性的

这是一个粗略的实现,但希望能让你了解如何实现一个图库,在这里你可以点击这些照片。当然,你仍然需要做一些CSS之类的事情。这是不完整的。如果你有任何问题,请告诉我

var StateModel = Backbone.Model.extend({
  defaults: {
    visibleImage: 0
  },

  initialize: function(attributes, options) {
    this.photoCollection = options.photoCollection;
  },

  setIndex: function(photoIndex) {
    if(!this.photoCollection.length) return;

    if(photoIndex < 0) {
      photoIndex = this.photoCollection.length - 1;
    } else if(photoIndex >= this.photoCollection.length) {
      photoIndex = 0;
    }

    this.set('visibleImage', photoIndex);
  },

  setPrev: function() {
    this.setIndex(this.get('visibleImage') - 1);
  },

  setNext: function() {
    this.setIndex(this.get('visibleImage') + 1);
  }
});

var PhotoControls = Backbone.View.extend({
  tagName: 'div',

  initialize: function(options) {
    this.stateModel = options.stateModel;
    this.paginationPadding = options.paginationPadding;
  },

  render: function() {
    var that = this;
    this.$el.empty();

    var ctrlStyle = {cursor: 'pointer', display: 'inline-block', padding: '5px 10px', margin: '0px 5px', border: '1px solid #000'};

    this.$el.append($('<div><< Previous</div>')
      .css(ctrlStyle))
      .click(function() {
        that.stateModel.setNext();
      });

    // Display numbers
    var visibleImage = this.stateModel.get('visibleImage');
    var pgStart = Math.max(visibleImage - this.paginationPadding, 0);
    var pgEnd = Math.min(visibleImage + this.paginationPadding, this.stateModel.photoCollection.length - 1);
    for(var i = pgStart; i <= pgEnd; i++) {
      var $numEl = that.$el.append(
        $('<div>' + (i + 1) + '</div>')
          .css(ctrlStyle)
          .click(function() {
            that.stateModel.setIndex(i);
          });

        if(i == visibleImage) {
          $numEl.css({fontWeight: 'bold', textDecoration: 'underline'});
        }
      );
    }

    this.$el.$('<div>Next >></div>')
      .css(ctrlStyle))
      .click(function() {
        that.stateModel.setPrev();
      });

    return this;
  }
});

var PhotoView = Backbone.View.extend({
  render: function() {
    this.$el.html('<img src="' + this.model.get('url') + '" />');

    return this;
  }
});

var GalleryView = Backbone.View.extend({
  tagName: 'div',

  initialize: function(options) {
    this.paginationPadding = 2;

    this.collection = PhotosCollection();
    this.renderedViews = {};
    this.state = new StateModel(null, {photoCollection: this.collection});
    this.photoControls = new PhotoControls({
      stateModel: this.state,
      paginationPadding: this.paginationPadding
    }).render();
  },

  render: function() {
    if(this.photoView) {
      this.photoView.remove();
    }

    // Pre-fetch images before and after current one based on pagination padding
    var visibleImage = this.stateModel.get('visibleImage');
    var pgStart = Math.max(visibleImage - this.paginationPadding, 0);
    var pgEnd = Math.min(visibleImage + this.paginationPadding, this.stateModel.photoCollection.length - 1);

    for(var i = pgStart; i <= pgEnd; i++) {
      if(!this.renderedViews[fetchModel.cid]) {
        // Images will begin fetching as soon as the 'src' attribute is set on the 'img' element rendered by the view
        this.renderedViews[model.cid] = new PhotoView(this.collection.at(i));
        this.renderedViews[model.cid].render();
      }
      this.$el.html(this.photoView.render().el);
    }

    // Attach the view for the current image
    var renderModel = this.collection.at(this.state.get('visibleImage'));
    if(renderModel && this.renderedViews[renderModel.cid]) {
      this.photoView = this.renderedViews[renderModel.cid];
      this.$el.html(this.photoView.el);
    }

    this.$el.append(this.photoControls.el);

    return this;
  }
});
var StateModel=Backbone.Model.extend({
默认值:{
可见图像:0
},
初始化:函数(属性、选项){
this.photoCollection=options.photoCollection;
},
setIndex:函数(photoIndex){
如果(!this.photoCollection.length)返回;
if(感光指数<0){
photoIndex=this.photoCollection.length-1;
}else if(photoIndex>=this.photoCollection.length){
光指数=0;
}
此.set('visibleImage',photoIndex);
},
setPrev:function(){
this.setIndex(this.get('visibleImage')-1);
},
setNext:函数(){
this.setIndex(this.get('visibleImage')+1);
}
});
var光电控制=主干.View.extend({
标记名:“div”,
初始化:函数(选项){
this.stateModel=options.stateModel;
this.paginationPadding=options.paginationPadding;
},
render:function(){
var=这个;
这个。$el.empty();
var ctrlStyle={cursor:'pointer',display:'inline block',padding:'5px 10px',margin:'0px 5px',border:'1px solid#000'};
此.el.append($('>'))
.css(ctrlStyle))
。单击(函数(){
即.stateModel.setPrev();
});
归还这个;
}
});
var PhotoView=Backbone.View.extend({
render:function(){
此.$el.html(“”);
归还这个;
}
});
var GalleryView=Backbone.View.extend({
标记名:“div”,
初始化:函数(选项){
this.paginationPadding=2;
this.collection=photoscolection();
this.renderdeviews={};
this.state=newstatemodel(null,{photoCollection:this.collection});
this.photoControls=新的photoControls({
stateModel:this.state,
paginationPadding:this.paginationPadding
}).render();
},
render:function(){
如果(此照片视图){
this.photoView.remove();
}
//基于分页填充在当前图像之前和之后预取图像
var visibleImage=this.stateModel.get('visibleImage');
var pgStart=Math.max(visibleImage-this.paginationPadding,0);
var pgEnd=Math.min(visibleImage+this.paginationPadding,this.stateModel.photoCollection.length-1);

对于(var i=pgStart;i这很好,但它不能解决分页问题,也不能在gallery视图中保留多个照片视图。当您更改状态并删除当前照片视图时,我想将其存储在某个位置,以便我们可以返回。我只是对代码进行了显著的扩展和修改,以满足您的要求。请查看!哦,还有所以支持在开始和结束时环绕。关于简单的部分:如果你不将照片视图附加到DOM,gallery view如何跟踪它。我喜欢你不删除照片视图的建议,但是gallery view div的宽度不是必须要长得多,以便它可以存储每个照片视图吗?