mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
reactively determined Component class
This commit is contained in:
@@ -46,4 +46,43 @@ Template.item({
|
||||
// $(table).append(frag);
|
||||
//
|
||||
// console.log(TABLE.rows.length);
|
||||
//});
|
||||
//});
|
||||
|
||||
Span = UIComponent.extend({
|
||||
render: function (buf) {
|
||||
buf("<span style='background:red;margin:5px'>Hello</span>");
|
||||
}
|
||||
});
|
||||
|
||||
Div = UIComponent.extend({
|
||||
render: function (buf) {
|
||||
buf("<div style='background:blue;margin:5px'>World</div>");
|
||||
}
|
||||
});
|
||||
|
||||
Either = UIComponent.extend({
|
||||
render: function (buf) {
|
||||
buf(Div.create(),
|
||||
{
|
||||
type: function () { return window[Session.get('which')]; },
|
||||
args: {
|
||||
built: function () {
|
||||
var self = this;
|
||||
self.$("*").on('click', function (evt) {
|
||||
Session.set(
|
||||
'which',
|
||||
Session.get('which') === 'Div' ? 'Span' : 'Div');
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
{ type: Span });
|
||||
}
|
||||
});
|
||||
|
||||
Meteor.startup(function () {
|
||||
Session.set('which', 'Span');
|
||||
|
||||
var x = Either.create({isRoot: true});
|
||||
x.attach(document.body);
|
||||
});
|
||||
|
||||
@@ -94,33 +94,16 @@ Component({
|
||||
_populate: function (div) {
|
||||
var self = this;
|
||||
|
||||
var strs = [];
|
||||
var randomString = Random.id();
|
||||
var commentUid = 1;
|
||||
var componentsToAttach = {};
|
||||
var buf = makeRenderBuffer(self);
|
||||
self.render(buf);
|
||||
|
||||
self.render(function (/*args*/) {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var arg = arguments[i];
|
||||
if (typeof arg === 'string') {
|
||||
strs.push(arg);
|
||||
} else if (arg instanceof Component) {
|
||||
var commentString = randomString + '_' + (commentUid++);
|
||||
strs.push('<!--', commentString, '-->');
|
||||
self.add(arg);
|
||||
componentsToAttach[commentString] = arg;
|
||||
} else {
|
||||
throw new Error("Expected string or Component");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var html = strs.join('');
|
||||
var html = buf.getHtml();
|
||||
|
||||
$(div).append(html);
|
||||
var start = div.firstChild;
|
||||
var end = div.lastChild;
|
||||
|
||||
var componentsToAttach = buf.componentsToAttach;
|
||||
// walk div and replace comments with Components
|
||||
|
||||
var wireUpDOM = function (parent) {
|
||||
@@ -182,6 +165,7 @@ Component({
|
||||
|
||||
if (c.firstRun) {
|
||||
var div = makeSafeDiv();
|
||||
// capture reactivity:
|
||||
var info = self._populate(div);
|
||||
|
||||
if (! div.firstChild)
|
||||
@@ -191,6 +175,7 @@ Component({
|
||||
self.start = info.start || div.firstChild;
|
||||
self.end = info.end || div.lastChild;
|
||||
} else {
|
||||
// capture reactivity:
|
||||
self._rebuild(c.builtChildren);
|
||||
}
|
||||
|
||||
@@ -593,6 +578,38 @@ Component({
|
||||
self._computations.push(c);
|
||||
|
||||
return c;
|
||||
},
|
||||
|
||||
replaceChild: function (oldChild, newChild) {
|
||||
var self = this;
|
||||
|
||||
self._requireBuilt();
|
||||
oldChild._requireBuilt();
|
||||
if (! oldChild.isAttached)
|
||||
throw new Error("Child to replace must be attached");
|
||||
|
||||
var lastNode = oldChild.lastNode();
|
||||
var parentNode = lastNode.parentNode;
|
||||
var nextNode = lastNode.nextSibling;
|
||||
|
||||
oldChild.remove();
|
||||
self.insertBefore(newChild, nextNode, parentNode);
|
||||
},
|
||||
|
||||
swapChild: function (oldChild, newChild) {
|
||||
var self = this;
|
||||
|
||||
self._requireBuilt();
|
||||
oldChild._requireBuilt();
|
||||
if (! oldChild.isAttached)
|
||||
throw new Error("Child to swap out must be attached");
|
||||
|
||||
var lastNode = oldChild.lastNode();
|
||||
var parentNode = lastNode.parentNode;
|
||||
var nextNode = lastNode.nextSibling;
|
||||
|
||||
oldChild.detach();
|
||||
self.insertBefore(newChild, nextNode, parentNode);
|
||||
}
|
||||
|
||||
// If Component is ever emptied, it gets an empty comment node.
|
||||
|
||||
@@ -16,6 +16,7 @@ Package.on_use(function (api) {
|
||||
api.add_files(['base.js',
|
||||
'lifecycle.js',
|
||||
'tree.js',
|
||||
'render.js',
|
||||
'dom.js',
|
||||
'forms.js',
|
||||
'components.js',
|
||||
|
||||
65
packages/ui/render.js
Normal file
65
packages/ui/render.js
Normal file
@@ -0,0 +1,65 @@
|
||||
var Component = UIComponent;
|
||||
|
||||
|
||||
makeRenderBuffer = function (component, options) {
|
||||
var isPreview = !! options && options.preview;
|
||||
|
||||
var strs = [];
|
||||
var componentsToAttach = {};
|
||||
var randomString = Random.id();
|
||||
var commentUid = 1;
|
||||
|
||||
var handle = function (arg) {
|
||||
if (typeof arg === 'string') {
|
||||
strs.push(arg);
|
||||
} else if (arg instanceof Component) {
|
||||
var commentString = randomString + '_' + (commentUid++);
|
||||
strs.push('<!--', commentString, '-->');
|
||||
component.add(arg);
|
||||
componentsToAttach[commentString] = arg;
|
||||
} else if (arg.type) {
|
||||
// `{type: componentTypeOrFunction, args: object}`
|
||||
if (Component.isType(arg.type)) {
|
||||
handle(arg.type.create(arg.args));
|
||||
} else if (typeof arg.type === 'function') {
|
||||
var curType;
|
||||
component.autorun(function (c) {
|
||||
// capture reactivity:
|
||||
var type = arg.type();
|
||||
if (c.firstRun) {
|
||||
curType = type;
|
||||
} else if (component.stage !== Component.BUILT ||
|
||||
! component.hasChild(curChild)) {
|
||||
c.stop();
|
||||
} else if (type !== curType) {
|
||||
var oldChild = curChild;
|
||||
curType = type;
|
||||
Deps.nonreactive(function () {
|
||||
curChild = curType.create(arg.args);
|
||||
component.replaceChild(oldChild, curChild);
|
||||
});
|
||||
}
|
||||
});
|
||||
var curChild = curType.create(arg.args);
|
||||
handle(curChild);
|
||||
} else {
|
||||
throw new Error("Expected 'type' to be Component or function");
|
||||
}
|
||||
} else {
|
||||
throw new Error("Expected string or Component");
|
||||
}
|
||||
};
|
||||
|
||||
var buf = function (/*args*/) {
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
handle(arguments[i]);
|
||||
};
|
||||
|
||||
buf.getHtml = function () {
|
||||
return strs.join('');
|
||||
};
|
||||
|
||||
buf.componentsToAttach = componentsToAttach;
|
||||
|
||||
return buf;
|
||||
};
|
||||
@@ -132,6 +132,12 @@ Component({
|
||||
self._added();
|
||||
},
|
||||
|
||||
hasChild: function (comp) {
|
||||
this._requireNotDestroyed();
|
||||
|
||||
return this.children[comp.guid] === comp;
|
||||
},
|
||||
|
||||
extendHooks: {
|
||||
isRoot: function (value) {
|
||||
if (value)
|
||||
|
||||
Reference in New Issue
Block a user