Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit 2799341

Browse files
committed
make ref bindable
R=arv BUG= Review URL: https://codereview.appspot.com/59220044
1 parent ef5535a commit 2799341

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

src/TemplateBinding.js

+47-1
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,15 @@
326326
}
327327
}
328328

329+
var templateObserver;
330+
if (typeof MutationObserver == 'function') {
331+
templateObserver = new MutationObserver(function(records) {
332+
for (var i = 0; i < records.length; i++) {
333+
records[i].target.refChanged_();
334+
}
335+
});
336+
}
337+
329338
/**
330339
* Ensures proper API and content model for template elements.
331340
* @param {HTMLTemplateElement} opt_instanceRef The template element which
@@ -429,6 +438,25 @@
429438
}
430439

431440
mixin(HTMLTemplateElement.prototype, {
441+
bind: function(name, value, oneTime) {
442+
if (name != 'ref')
443+
return Element.prototype.bind.call(this, name, value, oneTime);
444+
445+
var self = this;
446+
var ref = oneTime ? value : value.open(function(ref) {
447+
self.setAttribute('ref', ref);
448+
self.refChanged_();
449+
});
450+
451+
this.setAttribute('ref', ref);
452+
this.refChanged_();
453+
if (oneTime)
454+
return;
455+
456+
this.unbind('ref');
457+
return this.bindings.ref = value;
458+
},
459+
432460
processBindingDirectives_: function(directives) {
433461
if (this.iterator_)
434462
this.iterator_.closeDeps();
@@ -450,6 +478,12 @@
450478
}
451479

452480
this.iterator_.updateDependencies(directives, this.model_);
481+
482+
if (templateObserver) {
483+
templateObserver.observe(this, { attributes: true,
484+
attributeFilter: ['ref'] });
485+
}
486+
453487
return this.iterator_;
454488
},
455489

@@ -458,7 +492,9 @@
458492
if (bindingDelegate)
459493
delegate_ = this.newDelegate_(bindingDelegate);
460494

461-
var content = this.ref_.content;
495+
if (!this.refContent_)
496+
this.refContent_ = this.ref_.content;
497+
var content = this.refContent_;
462498
var map = this.bindingMap_;
463499
if (!map || map.content !== content) {
464500
// TODO(rafaelw): Setup a MutationObserver on content to detect
@@ -510,10 +546,20 @@
510546
return this.delegate_ && this.delegate_.raw;
511547
},
512548

549+
refChanged_: function() {
550+
if (!this.iterator_ || this.refContent_ === this.ref_.content)
551+
return;
552+
553+
this.refContent_ = undefined;
554+
this.iterator_.valueChanged();
555+
this.iterator_.updateIteratedValue();
556+
},
557+
513558
clear: function() {
514559
this.model_ = undefined;
515560
this.delegate_ = undefined;
516561
this.bindings_ = undefined;
562+
this.refContent_ = undefined;
517563
if (!this.iterator_)
518564
return;
519565
this.iterator_.valueChanged();

tests/tests.js

+31
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,12 @@ suite('Template Instantiation', function() {
14991499
});
15001500

15011501
test('Update Ref', function(done) {
1502+
// Updating ref by observing the attribute is dependent on MutationObservers
1503+
if (typeof MutationObserver != 'function') {
1504+
done();
1505+
return;
1506+
}
1507+
15021508
var div = createTestHtml(
15031509
'<template id=A>Hi, {{}}</template>' +
15041510
'<template id=B>Hola, {{}}</template>' +
@@ -1516,7 +1522,32 @@ suite('Template Instantiation', function() {
15161522

15171523
}).then(function() {
15181524
assert.strictEqual(5, div.childNodes.length);
1525+
assert.strictEqual('Hola, Fry', div.childNodes[3].textContent);
1526+
assert.strictEqual('Hola, Leela', div.childNodes[4].textContent);
1527+
1528+
done();
1529+
});
1530+
});
1531+
1532+
test('Bound Ref', function(done) {
1533+
var div = createTestHtml(
1534+
'<template id=A>Hi, {{}}</template>' +
1535+
'<template id=B>Hola, {{}}</template>' +
1536+
'<template ref="{{ ref }}" repeat="{{ people }}"></template>');
1537+
var template = div.childNodes[2];
1538+
var model = { ref: 'A', people: ['Fry'] };
1539+
template.model = model;
1540+
1541+
then(function() {
1542+
assert.strictEqual(4, div.childNodes.length);
15191543
assert.strictEqual('Hi, Fry', div.childNodes[3].textContent);
1544+
1545+
model.ref = 'B';
1546+
model.people.push('Leela');
1547+
1548+
}).then(function() {
1549+
assert.strictEqual(5, div.childNodes.length);
1550+
assert.strictEqual('Hola, Fry', div.childNodes[3].textContent);
15201551
assert.strictEqual('Hola, Leela', div.childNodes[4].textContent);
15211552

15221553
done();

0 commit comments

Comments
 (0)