mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
some docs changes from Geoff
This commit is contained in:
committed by
Nick Martin
parent
8f693a3175
commit
f6a5c903e0
@@ -841,54 +841,65 @@ These two expressions do the same thing:
|
||||
|
||||
Example:
|
||||
|
||||
// Show a dynamically updating list of items. Let the user click on an
|
||||
// item to select it. The selected item is given a CSS class so it
|
||||
// can be rendered differently.
|
||||
var frag = Meteor.ui.render(function() {
|
||||
return Meteor.ui.listChunk(Posts.find(),
|
||||
function(post) {
|
||||
var cls = Session.equals("selected_post", post._id) ?
|
||||
"selected" : "";
|
||||
return "<div class='" + cls + "'>" + post.title + "</div>";
|
||||
}, { events: {
|
||||
'click': function() {
|
||||
Session.set("selected_post", this._id);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
<template name="posts_view">
|
||||
{{dstache}}! Show a dynamically updating list of items. Let the user click on an
|
||||
item to select it. The selected item is given a CSS class so it
|
||||
can be rendered differently. }}
|
||||
|
||||
document.body.appendChild(frag);
|
||||
{{dstache}}#each posts}}
|
||||
{{dstache}}> post_item }}
|
||||
{{dstache}}/each}}
|
||||
</{{! }}template>
|
||||
|
||||
// In this code, when the user clicks on an item to select it, the
|
||||
// render function is called twice: once to rerender the item
|
||||
// that lost the selection, and once to rerender the item that gained
|
||||
// the selection.
|
||||
<template name="post_item">
|
||||
<div class="{{dstache}}post_class}}">{{dstache}}title}}</div>
|
||||
</{{! }}template>
|
||||
|
||||
///// in JS file
|
||||
Template.posts_view.posts = function() {
|
||||
return Posts.find();
|
||||
};
|
||||
|
||||
Template.post_item.post_class = function() {
|
||||
return Session.equals("selected_post", this._id) ?
|
||||
"selected" : "";
|
||||
};
|
||||
|
||||
Template.post_item.events = {
|
||||
'click': function() {
|
||||
Session.set("selected_post", this._id);
|
||||
}
|
||||
};
|
||||
|
||||
// Using Session.equals here means that when the user clicks
|
||||
// on an item and changes the selection, only the newly selected
|
||||
// and the newly unselected items are re-rendered.
|
||||
//
|
||||
// If Session.get had been used instead of Session.equals, then when
|
||||
// the user clicked on an item, the render function would have to
|
||||
// called once for every Post shown in the list.
|
||||
|
||||
// If Session.get had been used instead of Session.equals, then
|
||||
// when the selection changed, all the items would be re-rendered.
|
||||
|
||||
<h2 id="meteor_ui"><span>Meteor.ui</span></h2>
|
||||
|
||||
`Meteor.ui` provides building blocks for creating reactive UIs out of strings of
|
||||
HTML, making it easy to create DOM elements that update
|
||||
automatically as data changes in
|
||||
[`Session`](#session) variables or in a
|
||||
[`Meteor.Collection`](#meteor_collection). Meteor's built-in templates already use these functions, but if you have a preferred way to generate HTML,
|
||||
are integrating a new template langauge with Meteor, or need to compose a reactive
|
||||
[`Meteor.Collection`](#meteor_collection). Meteor's built-in templates already use these functions, but if you prefer a different way of generating HTML,
|
||||
are integrating a new template language with Meteor, or need to compose a reactive
|
||||
snippet of HTML on the fly, this package has what you need.
|
||||
|
||||
This package is implemented on top of [`Meteor.deps`](#meteor_deps), which provides the
|
||||
data dependency tracking and invalidation system, while `Meteor.ui` contributes
|
||||
the ability to turn HTML into DOM elements, keep track of regions of the DOM that
|
||||
need updating, and "patch" old DOM content with new, recalculated content.
|
||||
need updating, and patch old DOM content with new, recalculated content.
|
||||
|
||||
{{> api_box render}}
|
||||
|
||||
You provide a function `html_func` that returns HTML. This function is run in a
|
||||
reactive context, which records accesses to any reactive data sources
|
||||
(such as [`Session`](#session)), and the resulting HTML is rendered as
|
||||
You provide a function `html_func` that returns a string containing HTML. This
|
||||
function is used to create a DocumentFragment containing nodes that reactively
|
||||
updating in response to data changes.
|
||||
|
||||
`html_func` is run in a reactive context, which records accesses to any reactive data sources (such as [`Session`](#session)), and the resulting HTML is rendered as
|
||||
a DocumentFragment. The DOM elements in this returned
|
||||
DocumentFragment are sensitive to changes to the previously accessed data,
|
||||
in that if the data accessed from within `html_func` changes, then `html_func`
|
||||
@@ -898,17 +909,15 @@ There are two potential pitfalls to overwriting parts of the DOM with replacemen
|
||||
elements, as `render` must do during an update.
|
||||
One is that we might end up doing a lot
|
||||
of extra work, for example re-rendering the entire page whenever the
|
||||
database changes. The other is that re-rendering might "reset" form controls,
|
||||
database changes. The other is that re-rendering might reset form controls,
|
||||
for example replacing a text field that the user is typing in with a fresh, empty
|
||||
one that doesn't have focus. Ideally, small database changes would produce
|
||||
small, localized DOM updates, and the identity of input controls would be preserved
|
||||
even in the presence of reactive changes to their surroundings.
|
||||
|
||||
To this end, `render` provides facilities that affect how updating is performed, always
|
||||
with the goal of supporting the illusion of "replacing the old HTML with the new
|
||||
HTML."
|
||||
By providing some hints, you can enable `render` to patch DOM elements in place, rather than replacing them.
|
||||
|
||||
<span id="patching">__Patching__</span> is triggered by the presence of elements
|
||||
<span id="patching">Patching</span> is triggered by the presence of elements
|
||||
with `id` or `name` attributes,
|
||||
and it aims to preserve the old elements while still effecting the same overall
|
||||
update. If the old HTML and the new HTML both declare an element with the same `id`,
|
||||
@@ -918,31 +927,13 @@ the only the old element's siblings, children, and attributes are changed. The
|
||||
nearest ancestor with a `name` or `id` tag. An element with an `id` or `name` attribute is called a "labeled" element. To be sure that a form field is preserved
|
||||
across updates, then, you should either assign it a unique `id` or give it a unique `name` within some enclosing element with a unique `id`.
|
||||
|
||||
{{#warning}}
|
||||
The exact set of attributes used to hint patching may change. The HTML5
|
||||
spec frowns on adding the `name` attribute to an arbitrary element
|
||||
where it is not meaningful or might have a historical meaning.
|
||||
{{/warning}}
|
||||
|
||||
The patcher is quite powerful and can preserve any number of labeled elements nested
|
||||
within other labeled or unlabeled elements. It won't preserve a node if it can't
|
||||
match its label uniquely, or if the changes it needs to make are impossible without
|
||||
recreating or reparenting the node anyway: different tag name, different parents,
|
||||
different order, etc. However, these cases are easy to avoid when you want node
|
||||
preservation, and if any of them occur, recovery is graceful; node identity
|
||||
is the only casualty, not correctness.
|
||||
|
||||
__Chunks__ provide a way to specify regions of your HTML that should be tracked and
|
||||
updated without triggering a re-render of their parent region. See [`Meteor.ui.chunk`](#meteor_ui_chunk).
|
||||
The patching process preserves all labeled elements, regardless of their depth or nesting, as long as this can be done without reparenting or recreating the elements. It is possible to create situations where patching is impossible; for example, changing the tag name of an element, or moving the element to a different position, in which case the element in question is not preserved.
|
||||
|
||||
The DocumentFragment returned by `Meteor.ui.render` can be inserted anywhere
|
||||
in the DOM you like, and the DOM elements will continue to update until they are
|
||||
removed from the document. Specifically, whenever [`Meteor.flush`](#meteor_flush)
|
||||
runs — either because it was called explicitly or because there are data changes
|
||||
that need to be reflected in the DOM — any "offscreen" elements that aren't
|
||||
descendents of `document` are removed from Meteor's data structures and no longer
|
||||
update. This also means that a DocumentFragment newly created by `Meteor.ui.render`
|
||||
must be added to the document before a `flush` or a return to the browser's event loop.
|
||||
removed from the document. For the details, see [`Meteor.flush`](#meteor_flush).
|
||||
|
||||
If you want a region of your HTML to be able to update independently of the other HTML around it, wrap it in a [`Meteor.ui.chunk`](#meteor_ui_chunk).
|
||||
|
||||
The `events` option lets you hook up event handlers to
|
||||
the DOM nodes. If you provide `event_data`, it will be
|
||||
@@ -983,15 +974,11 @@ Example:
|
||||
|
||||
{{> api_box chunk}}
|
||||
|
||||
When generating HTML from a function passed to [`Meteor.ui.render`](#meteor_ui_render),
|
||||
`Meteor.ui.chunk` provides a way to mark a "chunk" (or sub-string) of the HTML
|
||||
as individually and independently reactive. As with `render`, you provide
|
||||
a function `html_func` to generate HTML, and this function is run in a reactive
|
||||
context and re-run as necessary when data changes. However, instead of returning
|
||||
a live DocumentFragment, this function returns a string of HTML, essentially the
|
||||
output of `html_func` annotated with some special comments. The "wiring up" of data
|
||||
to DOM elements is deferred until the enclosing call the `render` is reached —
|
||||
in other words, until the HTML becomes DOM.
|
||||
When generating HTML from a function passed to [`Meteor.ui.render`](#meteor_ui_render), you can use `Meteor.ui.chunk` to mark a substring of the HTML as separately reactive. If the data used to generate that substring changes, only the elements corresponding to that substring will be updated, not the elements before and after it.
|
||||
|
||||
Like `render`, `Meteor.ui.chunk` takes a function `html_func` that returns a HTML string. It calls that function, records the data that the function used (using a [reactive context](#meteor_ui_deps)), and arranges to rerun the function as necessary whenever the data changes. What's different from `render` is that it returns another HTML string, not a DocumentFragment. So, unlike `render`, `chunk` may be nested as deeply as you like, for example to render nested views or subtemplates.
|
||||
|
||||
`chunk` can also be used to attach events to part of an HTML string, in much the same way that they could be attached to DOM elements. When the string is parsed into DOM elements by `render`, the event handlers will automatically be hooked up.
|
||||
|
||||
HTML generation in web apps is typically recursive, whether it be
|
||||
through function calls, sub-views, template-includes, "partials," or
|
||||
|
||||
Reference in New Issue
Block a user