Skip to content

Commit

Permalink
merged with master
Browse files Browse the repository at this point in the history
  • Loading branch information
justinbmeyer committed May 18, 2015
2 parents 7b0e392 + dce04a5 commit 542a6ce
Show file tree
Hide file tree
Showing 69 changed files with 1,065 additions and 954 deletions.
4 changes: 4 additions & 0 deletions build/config_meta_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ module.exports = function(){
if(load.address.indexOf("node_modules") >= 0) {
return true;
}
}, function(moduleName) {
if(moduleName.indexOf('/system') !== -1) {
return true;
}
}])
}
};
Expand Down
20 changes: 18 additions & 2 deletions component/component.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
@description Create widgets that use a template, a view-model
and custom tags.

Watch this video for an overview of can.Component, why you should use it, and a hello world example:

<iframe width="662" height="372" src="https://www.youtube.com/embed/BM1Jc3lVUrk" frameborder="0" allowfullscreen></iframe>

This video provides a more in depth overview of the API and goes over several examples of can.Components:

<iframe width="662" height="372" src="https://www.youtube.com/embed/ogX765S4iuc" frameborder="0" allowfullscreen></iframe>

Note: the videos above reference the `scope` property, which was replaced by the [can.Component::viewModel viewModel] property in 2.2.

@signature `< TAG [ATTR-NAME="{KEY}|ATTR-VALUE"] >`

Create an instance of a component on a particular
Expand Down Expand Up @@ -110,11 +120,15 @@ you'll render a template with many custom tags like:
</ui-panel>
</srchr-app>

### Extending can.Component
### Creating a can.Component

Use [can.Component.extend] to create a `can.Component` constructor function
that will automatically get initialized whenever the component's tag is
found.
found.

Note that inheriting from components works differently than other CanJS APIs. You can't call `.extend` on a particular component to create a "subclass" of that component.

Instead, components work more like HTML elements. To reuse functionality from a base component, build on top of it with parent components that wrap other components in their template and pass any needed viewModel properties via attributes.

### Tag

Expand Down Expand Up @@ -239,6 +253,8 @@ adds "!" to the message every time `<hello-world>` is clicked:
}
});

Components have the ability to bind to special [can.events.inserted inserted] and [can.events.removed removed] events that are called when a component's tag has been inserted into or removed from the page.

### Helpers

A component's [can.Component::helpers helpers] object provides [can.mustache.helper mustache helper] functions
Expand Down
30 changes: 10 additions & 20 deletions component/component_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1639,28 +1639,16 @@ steal("can-simple-dom", "can/util/vdom/build_fragment.js","can", "can/map/define

asyncTest('<content> node list cleans up properly, directly nested (#1625, #1627)', function() {
var items = [];
var viewModel = window.viewModel = new can.Map({
show: true
});

for (var i = 0; i < 100; i++) {
for (var i = 0; i < 2; i++) {
items.push({
// Random 5 character String
name: Math.random().toString(36)
.replace(/[^a-z]+/g, '').substr(0, 5),
foo: 'test ' + i
name: 'test ' + i,
parentAttrInContent: 'test ' + i
});
}

can.Component.extend({
tag: 'grandparent-component',
template: can.stache('{{#if show}}<parent-component></parent-component>{{/if}}'),
scope: viewModel
});

can.Component.extend({
tag: 'parent-component',
template: can.stache('{{#items}}<child-component>{{foo}}</child-component>{{/items}}'),
template: can.stache('{{#items}}<child-component>{{parentAttrInContent}}</child-component>{{/items}}'),
scope: {
items: items
}
Expand All @@ -1674,22 +1662,24 @@ steal("can-simple-dom", "can/util/vdom/build_fragment.js","can", "can/map/define
}
});

can.append(can.$("#qunit-fixture"), can.stache('<grandparent-component></grandparent-component>')());
can.append(can.$("#qunit-fixture"), can.stache('<parent-component></parent-component>')());

var old = can.unbindAndTeardown;
var count = 0;
can.unbindAndTeardown = function(name) {
if(name === 'foo') {
if(name === 'parentAttrInContent') {
count++;
}
return old.call(this, arguments);
};

can.remove(can.$("#qunit-fixture>*"));

// Dispatches async
setTimeout(function() {
equal(count, 100, '100 items unbound');
equal(count, 2, '2 items unbound');
can.unbindAndTeardown = old;
can.remove(can.$("#qunit-fixture>*"));

start();
}, 20);
});
Expand Down
11 changes: 11 additions & 0 deletions component/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ of using live-binding, we could listen to when offset changes and update the pag

@demo can/component/examples/paginate_events_next_update_page.html

Components have the ability to bind to special [can.events.inserted inserted] and [can.events.removed removed] events that are called when a component's tag has been inserted into or removed from the page:

events: {
"inserted": function(){
// called when the component's tag is inserted into the DOM
},
"removed": function(){
// called when the component's tag is removed from the DOM
}
}

## High performance template rendering

While [can.view.bindings] conveniently allows you to call a [can.Component::viewModel viewModel] method from a template like:
Expand Down
9 changes: 8 additions & 1 deletion component/extend.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,11 @@ used to render the component's template.
that is is used to render the component's template.

@option {can.Component.prototype.tempate} [template] Specifies the template
rendered within the custom element.
rendered within the custom element.

@body


Note that inheriting from components works differently than other CanJS APIs. You can't call `.extend` on a particular component to create a "subclass" of that component.

Instead, components work more like HTML elements. To reuse functionality from a base component, build on top of it with parent components that wrap other components in their template and pass any needed viewModel properties via attributes.
6 changes: 3 additions & 3 deletions component/leakscope.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ user content can read the component's view model.

Lets define what __outer scope__, __component's template__ and __user content__ mean.

If I have component `<my-widget>` in a template like:
If I have a `<hello-world>` component in a template like:

```
{{#data}}
Expand All @@ -38,12 +38,12 @@ The __outer scope__ of `<hello-world>` has `data` as its context. The __user co
`<hello-world>` is the template between its tags. In this case, the __user content__
is `{{subject}}`.

Finally, if `<my-widget>` is defined like:
Finally, if `<hello-world>` is defined like:

```
can.Component.extend({
tag: "hello-world",
tag: can.stache("{{greeting}} <content/>{{exclamation}}")
template: can.stache("{{greeting}} <content/>{{exclamation}}")
})
```

Expand Down
14 changes: 0 additions & 14 deletions compute/benchmark.html

This file was deleted.

1 change: 1 addition & 0 deletions compute/benchmark/benchmark.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script src="../../node_modules/steal/steal.js" main="can/compute/benchmark/compute_benchmark"></script>
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
steal('can/compute',
'can/compute/proto_compute.js',
'can/test/benchmarks.js',
'steal-benchmark',
'can/map',

function (can, Compute, benchmarks) {
function (can, Compute, b) {
/* jshint ignore:start */


b.suite("can/compute")

.add("compute that reads two props",
function () {
can.batch.start();
num++;
person.attr({
first: "Bob"+num,
last: "Marley"+num
});
can.batch.stop();
},{
setup: function(){
var person = new can.Map({
first: 'Bob',
last: 'Marley'
});
var c = new can.Compute(function() {
return person.attr('first') + person.attr('last');
});
c.bind('change', function() {});
var num = 0;
}
});

/*
module('can.compute');
test('create/bind/read', function() {
expect(0);
Expand Down Expand Up @@ -78,6 +106,6 @@ function (can, Compute, benchmarks) {
c.get();
},
function () {});
});
});*/
/* jshint ignore:end */
});
22 changes: 1 addition & 21 deletions compute/compute.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,7 @@

steal('can/util', 'can/util/bind', 'can/util/batch', 'can/compute/proto_compute.js', function (can, bind) {

// ## Reading Helpers
//
// The following methods are used to call a function that relies on
// observable data and to track the observable events which should
// be listened to when changes occur.
// To do this, [`can.__reading(observable, event)`](#can-__reading) is called to
// "broadcast" the corresponding event on each read.
//
// ### Observed
//
// An "Observed" is an object of observable objects and events that
// a function relies on. These objects and events must be listened to
// in order to determine when to check a function for updates.
// This looks like the following:
//
// {
// "map1|first": {obj: map, event: "first"},
// "map1|last" : {obj: map, event: "last"}
// }
//
// Each object-event pair is mapped so no duplicates will be listed.


can.compute = function (getterSetter, context, eventName, bindOnce) {

Expand Down
2 changes: 1 addition & 1 deletion compute/compute.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ are observable, it means that the view of that Control will update itself whenev
of the compute updates. Here's a simple slider that works off of a compute:

```
var project = new Observe({
var project = new can.Map({
name: 'A Very Important Project',
percentDone: .35
});
Expand Down
Loading

0 comments on commit 542a6ce

Please sign in to comment.