Skip to content

Commit 3cfc961

Browse files
committed
Merge pull request #13424 from robbiepitts/deprecate-ember-binding
[DEPRECATE] Deprecate Ember.Binding
2 parents 715fb54 + bc8903f commit 3cfc961

File tree

16 files changed

+339
-91
lines changed

16 files changed

+339
-91
lines changed

packages/ember-glimmer/tests/integration/binding_integration_test.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@ moduleFor('Binding integration tests', class extends RenderingTest {
1818
template: 'two way: {{twoWayTest}}, string: {{stringTest}}, object: {{twoWayObjectTest}}, string object: {{stringObjectTest}}'
1919
});
2020

21-
this.render('{{foo-bar direction=direction displacement=displacement}}', {
22-
direction: 'down',
23-
displacement: {
24-
distance: 10
25-
}
26-
});
21+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
22+
' using an `alias` computed property instead.';
23+
24+
expectDeprecation(() => {
25+
this.render('{{foo-bar direction=direction displacement=displacement}}', {
26+
direction: 'down',
27+
displacement: {
28+
distance: 10
29+
}
30+
});
31+
}, deprecationMessage);
2732

2833
this.assertText('two way: down, string: down, object: 10, string object: 10');
2934

packages/ember-glimmer/tests/integration/helpers/unbound-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,10 @@ moduleFor('Helpers test: {{unbound}}', class extends RenderingTest {
252252

253253
this.render(`{{unbound (repeat foo count=bar)}} {{repeat foo count=bar}} {{unbound (repeat foo count=2)}} {{repeat foo count=4}}`, {
254254
foo: 'X',
255-
numRepeatsBinding: 'bar',
256255
bar: 5
257256
});
258257

258+
259259
this.assertText('XXXXX XXXXX XX XXXX');
260260

261261
this.runTask(() => this.rerender());

packages/ember-metal/lib/binding.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Logger from 'ember-console';
22
import { context, ENV } from 'ember-environment';
33
import run from 'ember-metal/run_loop';
4-
import { assert } from 'ember-metal/debug';
4+
import { assert, deprecate } from 'ember-metal/debug';
55
import { get } from 'ember-metal/property_get';
66
import { trySet } from 'ember-metal/property_set';
77
import { guidFor } from 'ember-metal/utils';
@@ -43,6 +43,7 @@ function Binding(toPath, fromPath) {
4343
/**
4444
@class Binding
4545
@namespace Ember
46+
@deprecated See http://emberjs.com/deprecations/v2.x#toc_ember-binding
4647
@public
4748
*/
4849

@@ -144,13 +145,13 @@ Binding.prototype = {
144145
connect(obj) {
145146
assert('Must pass a valid object to Ember.Binding.connect()', !!obj);
146147

147-
let fromObj, fromPath;
148+
let fromObj, fromPath, possibleGlobal;
148149

149150
// If the binding's "from" path could be interpreted as a global, verify
150151
// whether the path refers to a global or not by consulting `Ember.lookup`.
151152
if (isGlobalPath(this._from)) {
152153
let name = getFirstKey(this._from);
153-
let possibleGlobal = context.lookup[name];
154+
possibleGlobal = context.lookup[name];
154155

155156
if (possibleGlobal) {
156157
fromObj = possibleGlobal;
@@ -175,6 +176,10 @@ Binding.prototype = {
175176

176177
addListener(obj, 'willDestroy', this, 'disconnect');
177178

179+
fireDeprecations(possibleGlobal,
180+
this._oneWay,
181+
(!possibleGlobal && !this._oneWay));
182+
178183
this._readyToSync = true;
179184
this._fromObj = fromObj;
180185
this._fromPath = fromPath;
@@ -281,6 +286,32 @@ Binding.prototype = {
281286

282287
};
283288

289+
function fireDeprecations(deprecateGlobal, deprecateOneWay, deprecateAlias) {
290+
let deprecateGlobalMessage = '`Ember.Binding` is deprecated. Since you' +
291+
' are binding to a global consider using a service instead.';
292+
let deprecateOneWayMessage = '`Ember.Binding` is deprecated. Since you' +
293+
' are using a `oneWay` binding consider using a `readOnly` computed' +
294+
' property instead.';
295+
let deprecateAliasMessage = '`Ember.Binding` is deprecated. Consider' +
296+
' using an `alias` computed property instead.';
297+
298+
deprecate(deprecateGlobalMessage, !deprecateGlobal, {
299+
id: 'ember-metal.binding',
300+
until: '3.0.0',
301+
url: 'http://emberjs.com/deprecations/v2.x#toc_ember-binding'
302+
});
303+
deprecate(deprecateOneWayMessage, !deprecateOneWay, {
304+
id: 'ember-metal.binding',
305+
until: '3.0.0',
306+
url: 'http://emberjs.com/deprecations/v2.x#toc_ember-binding'
307+
});
308+
deprecate(deprecateAliasMessage, !deprecateAlias, {
309+
id: 'ember-metal.binding',
310+
until: '3.0.0',
311+
url: 'http://emberjs.com/deprecations/v2.x#toc_ember-binding'
312+
});
313+
}
314+
284315
function mixinProperties(to, from) {
285316
for (var key in from) {
286317
if (from.hasOwnProperty(key)) {

packages/ember-metal/tests/binding/connect_test.js

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,26 @@ testBoth('Connecting a binding between two properties', function(get, set) {
5454
// a.bar -> a.foo
5555
var binding = new Binding('foo', 'bar');
5656

57-
performTest(binding, a, a, get, set);
57+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
58+
' `alias` computed property instead.';
59+
60+
expectDeprecation(() => {
61+
performTest(binding, a, a, get, set);
62+
}, deprecationMessage);
63+
});
64+
65+
testBoth('Connecting a oneWay binding raises a deprecation',
66+
function(get, set) {
67+
var a = { foo: 'FOO', bar: 'BAR' };
68+
69+
// a.bar -> a.foo
70+
var binding = new Binding('foo', 'bar').oneWay();
71+
72+
let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
73+
' are using a `oneWay` binding consider using a `readOnly` computed' +
74+
' property instead.';
75+
76+
expectDeprecation(() => { binding.connect(a); }, deprecationMessage);
5877
});
5978

6079
testBoth('Connecting a binding between two objects', function(get, set) {
@@ -64,7 +83,12 @@ testBoth('Connecting a binding between two objects', function(get, set) {
6483
// b.bar -> a.foo
6584
var binding = new Binding('foo', 'b.bar');
6685

67-
performTest(binding, a, b, get, set);
86+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
87+
' `alias` computed property instead.';
88+
89+
expectDeprecation(() => {
90+
performTest(binding, a, b, get, set);
91+
}, deprecationMessage);
6892
});
6993

7094
testBoth('Connecting a binding to path', function(get, set) {
@@ -78,7 +102,12 @@ testBoth('Connecting a binding to path', function(get, set) {
78102
// globalB.b.bar -> a.foo
79103
var binding = new Binding('foo', 'GlobalB.b.bar');
80104

81-
performTest(binding, a, b, get, set);
105+
let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
106+
' are binding to a global consider using a service instead.';
107+
108+
expectDeprecation(() => {
109+
performTest(binding, a, b, get, set);
110+
}, deprecationMessage);
82111

83112
// make sure modifications update
84113
b = { bar: 'BIFF' };
@@ -97,11 +126,15 @@ testBoth('Calling connect more than once', function(get, set) {
97126
// b.bar -> a.foo
98127
var binding = new Binding('foo', 'b.bar');
99128

100-
performTest(binding, a, b, get, set, function () {
101-
binding.connect(a);
129+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
130+
' `alias` computed property instead.';
102131

103-
binding.connect(a);
104-
});
132+
expectDeprecation(() => {
133+
performTest(binding, a, b, get, set, function () {
134+
binding.connect(a);
135+
binding.connect(a);
136+
});
137+
}, deprecationMessage);
105138
});
106139

107140
QUnit.test('inherited bindings should sync on create', function() {
@@ -111,10 +144,13 @@ QUnit.test('inherited bindings should sync on create', function() {
111144
bind(this, 'foo', 'bar.baz');
112145
};
113146

114-
a = new A();
147+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider using an' +
148+
' `alias` computed property instead.';
149+
150+
expectDeprecation(() => { a = new A(); }, deprecationMessage);
151+
115152
set(a, 'bar', { baz: 'BAZ' });
116153
});
117154

118155
equal(get(a, 'foo'), 'BAZ', 'should have synced binding on new obj');
119156
});
120-

packages/ember-metal/tests/binding/sync_test.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ testBoth('bindings should not sync twice in a single run loop', function(get, se
3535
b = {
3636
a: a
3737
};
38-
bind(b, 'foo', 'a.foo');
38+
39+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
40+
' using an `alias` computed property instead.';
41+
42+
expectDeprecation(() => {
43+
bind(b, 'foo', 'a.foo');
44+
}, deprecationMessage);
3945
});
4046

4147
// reset after initial binding synchronization
@@ -68,7 +74,13 @@ testBoth('bindings should not infinite loop if computed properties return object
6874
b = {
6975
a: a
7076
};
71-
bind(b, 'foo', 'a.foo');
77+
78+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
79+
' using an `alias` computed property instead.';
80+
81+
expectDeprecation(() => {
82+
bind(b, 'foo', 'a.foo');
83+
}, deprecationMessage);
7284
});
7385

7486
deepEqual(get(b, 'foo'), ['foo', 'bar'], 'the binding should sync');
@@ -86,12 +98,21 @@ testBoth('bindings should do the right thing when observers trigger bindings in
8698
b = {
8799
a: a
88100
};
89-
bind(b, 'foo', 'a.foo');
101+
102+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
103+
' using an `alias` computed property instead.';
104+
105+
expectDeprecation(() => {
106+
bind(b, 'foo', 'a.foo');
107+
}, deprecationMessage);
90108

91109
c = {
92110
a: a
93111
};
94-
bind(c, 'foo', 'a.foo');
112+
113+
expectDeprecation(() => {
114+
bind(c, 'foo', 'a.foo');
115+
}, deprecationMessage);
95116
});
96117

97118
addObserver(b, 'foo', function() {
@@ -116,7 +137,13 @@ testBoth('bindings should not try to sync destroyed objects', function(get, set)
116137
b = {
117138
a: a
118139
};
119-
bind(b, 'foo', 'a.foo');
140+
141+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
142+
' using an `alias` computed property instead.';
143+
144+
expectDeprecation(() => {
145+
bind(b, 'foo', 'a.foo');
146+
}, deprecationMessage);
120147
});
121148

122149
run(function() {
@@ -133,7 +160,13 @@ testBoth('bindings should not try to sync destroyed objects', function(get, set)
133160
b = {
134161
a: a
135162
};
136-
bind(b, 'foo', 'a.foo');
163+
164+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
165+
' using an `alias` computed property instead.';
166+
167+
expectDeprecation(() => {
168+
bind(b, 'foo', 'a.foo');
169+
}, deprecationMessage);
137170
});
138171

139172
run(function() {

packages/ember-runtime/tests/ext/mixin_test.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ QUnit.test('Defining a property ending in Binding should setup binding when appl
1414
var obj = { bar: { baz: 'BIFF' } };
1515

1616
run(function() {
17-
MyMixin.apply(obj);
17+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
18+
' using an `alias` computed property instead.';
19+
20+
expectDeprecation(() => {
21+
MyMixin.apply(obj);
22+
}, deprecationMessage);
1823
});
1924

2025
ok(get(obj, 'fooBinding') instanceof Binding, 'should be a binding object');
@@ -33,7 +38,12 @@ QUnit.test('Defining a property ending in Binding should apply to prototype chil
3338
obj = { bar: { baz: 'BIFF' } };
3439

3540
run(function() {
36-
MyMixin.apply(obj);
41+
let deprecationMessage = '`Ember.Binding` is deprecated. Consider' +
42+
' using an `alias` computed property instead.';
43+
44+
expectDeprecation(() => {
45+
MyMixin.apply(obj);
46+
}, deprecationMessage);
3747
});
3848

3949

packages/ember-runtime/tests/legacy_1x/mixins/observable/observable_test.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,14 @@ QUnit.test('nested dependent keys should propagate after they update', function(
528528
})
529529
});
530530

531-
bindObj = ObservableObject.extend({
532-
priceBinding: 'DepObj.price'
533-
}).create();
531+
let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
532+
' are binding to a global consider using a service instead.';
533+
534+
expectDeprecation(() => {
535+
bindObj = ObservableObject.extend({
536+
priceBinding: 'DepObj.price'
537+
}).create();
538+
}, deprecationMessage);
534539
});
535540

536541
equal(bindObj.get('price'), 5, 'precond - binding propagates');
@@ -835,7 +840,7 @@ QUnit.test('removing an observer inside of an observer shouldn’t cause any pro
835840

836841

837842

838-
QUnit.module('Bind function ', {
843+
QUnit.module('Bind function', {
839844
setup() {
840845
objectA = ObservableObject.create({
841846
name: 'Sproutcore',
@@ -865,7 +870,12 @@ QUnit.module('Bind function ', {
865870
QUnit.test('should bind property with method parameter as undefined', function() {
866871
// creating binding
867872
run(function() {
868-
objectA.bind('name', 'Namespace.objectB.normal', undefined);
873+
let deprecationMessage = '`Ember.Binding` is deprecated. Since you' +
874+
' are binding to a global consider using a service instead.';
875+
876+
expectDeprecation(() => {
877+
objectA.bind('name', 'Namespace.objectB.normal', undefined);
878+
}, deprecationMessage);
869879
});
870880

871881
// now make a change to see if the binding triggers.

0 commit comments

Comments
 (0)