I have a scrollview i'm inserting divs into.
however, the content of these divs are being rendered by javascript templating engine.
when famo.us initially creates this page, it seems it calculate the height of the div content to be zero, so the divs in the scrollview all end up being on top of each other. I'm guessing this is because template rendering happens a couple of ticks later..
is there a way to force famo.us to recalculate/reflow its layout?
I too owe johntraver a beer for his excellent answers on famo.us questions here. This is work derived from one of his previous answers, I use it for surfaces on scrollviews with dynamic html content (and height):
/* AutoSurface.js */
define(function(require, exports, module) {
var Surface = require('famous/core/Surface');
var Entity = require('famous/core/Entity');
function AutoSurface(options) {
Surface.apply(this, arguments);
this.hasTrueSize = false;
this._superCommit = Surface.prototype.commit;
}
AutoSurface.prototype = Object.create(Surface.prototype);
AutoSurface.prototype.constructor = AutoSurface;
AutoSurface.prototype.commit = function commit(context) {
this._superCommit(context);
if (!this.hasTrueSize) {
this.trueHeight = Entity.get(this.id)._currTarget.clientHeight;
this.setSize([undefined,this.trueHeight]);
this.hasTrueSize = true;
}
}
module.exports = AutoSurface;
});
Commit is called every tick so you should be able to wait until you have a height > 0 or what you need before you set hasTrueSize = true.
This is very similar to the answer I just posted here.
how best to create a single scrollable view in famo.us?
You can wrap your true-sized surfaces in a sized modifier. This allows for scrollview to know the actual height of the surfaces within, and thus properly scroll. I am using the _currTarget of surface in the Modifiers sizeFrom method. The ternary operation is to prevent errors pre-deploy of the surface.
Here is that example revised for multiple cells in scrollview.. Hope it helps!
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var RenderNode = require('famous/core/RenderNode');
var Modifier = require('famous/core/Modifier');
var Scrollview = require('famous/views/Scrollview');
var context = Engine.createContext();
var content = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod \
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, \
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo \
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse \
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non \
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
var scrollview = new Scrollview();
var surfaces = [];
scrollview.sequenceFrom(surfaces);
for (var i = 0; i < 10; i++) {
var surface = new Surface({
size:[undefined,true],
content: content,
properties:{
fontSize:'24px',
backgroundColor:'hsl('+(i*360/20)+',100%,50%)'
}
})
surface.pipe(scrollview);
surface.node = new RenderNode();
surface.mod = new Modifier();
surface.mod.sizeFrom(function(){
target = this._currTarget;
return target ? [undefined,target.offsetHeight] : [undefined,true];
}.bind(surface));
surface.node.add(surface.mod).add(surface);
surfaces.push(surface.node);
};
context.add(scrollview);
Instead of hacking deploy
of using a sizeFrom
-modifier, there is a much easier hack:
Let a surface return it's actual calculated height instead of it's specified height.
Override the default getSize
function with this:
surface.getSize = function() { return this._size || this.size }
Full example in a JSFiddle
Warning: This breaks setting the Size with a modifier higher up the rendering tree. (But since you set size explictly anyway, this should not be a problem)
来源:https://stackoverflow.com/questions/24463465/how-to-make-famo-us-recalculate-sizes