Skip to content

Instantly share code, notes, and snippets.

@ASH-Michael
Last active February 7, 2020 17:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ASH-Michael/ad3078e054874df79bdfeb1f2089de33 to your computer and use it in GitHub Desktop.
Save ASH-Michael/ad3078e054874df79bdfeb1f2089de33 to your computer and use it in GitHub Desktop.
Overwriting Computed Properties
import Controller from '@ember/controller';
import { computed, set } from '@ember/object';
import { alias, oneWay } from '@ember/object/computed';
export default Controller.extend({
// demo 1
color1: 'red',
color2: 'blue',
color3: computed('color1', 'color2', function() {
const same = this._checkIfSame(this.color1, this.color2);
return same ? this.color1 : this._getSecondaryColor(this.color1, this.color2);
}),
// demo 2
color4: 'red',
color5: 'blue',
color4oneWay: oneWay('color4'),
color6: computed('color4', 'color5', function() {
const same = this._checkIfSame(this.color4, this.color5);
return same ? this.color4 : this._getSecondaryColor(this.color4, this.color5);
}),
// demo 3
color7: 'red',
color8: 'blue',
color7alias: alias('color7'),
color9: computed('color7', 'color8', function() {
const same = this._checkIfSame(this.color7, this.color8);
return same ? this.color7 : this._getSecondaryColor(this.color7, this.color8);
}),
// demo 4
color10: 'red',
color11: 'blue',
colorObject: computed('color10', 'color11', function() {
const same = this._checkIfSame(this.color10, this.color11);
return {
primary1: this.color10,
primary2: this.color11,
secondary: same ? this.color10 : this._getSecondaryColor(this.color10, this.color11)
};
}),
_checkIfSame(color1, color2) {
return color1 === color2;
},
_getSecondaryColor(primary1, primary2) {
const primaryColors = [primary1, primary2];
if (primaryColors.includes('red') && primaryColors.includes('blue')) {
return 'purple';
}
if (primaryColors.includes('red') && primaryColors.includes('yellow')) {
return 'orange';
}
if (primaryColors.includes('blue') && primaryColors.includes('yellow')) {
return 'green';
}
},
actions: {
changeColor(property, color) {
set(this, property, color);
},
changeColorObject(color) {
set(this, 'colorObject.secondary', color);
}
}
});
<h1>Overwriting Computed Properties</h1>
<strong>Overview:
<ul>
<li>color1 and color2 are string properties</li>
<li>color1oneWay has a oneWay relationship with color1</li>
<li>color1alias is an alias of color1</li>
<li>color3 is a computed property (it returns the secondary product of color1 and color2)</li>
<li>colorObject is a computed object (it returns an object with 3 property/value pairs (primary1: color1, primary2: color2, secondary: [secondary product of color1 and color2])</li>
</ul>
</strong>
<h2>Demo1: Overwriting a computed property</h2>
<p>color1: ({{color1}}) + color2: ({{color2}}) = color3: ({{color3}})</p>
Change color1:
<button class="red" onclick={{action "changeColor" "color1" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color1" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color1" "blue"}}>blue</button>
<br>
<em>changing color1 directly will affect the color3 computed value, but only if color3 has not been set directly.</em>
<br>
<br>
Change color2:
<button class="red" onclick={{action "changeColor" "color2" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color2" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color2" "blue"}}>blue</button>
<br>
<em>changing color2 directly will affect the color3 computed value, but only if color3 has not been set directly.</em>
<br>
<br>
Change color3:
<button class="red" onclick={{action "changeColor" "color3" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color3" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color3" "blue"}}>blue</button>
<br>
<em>changing a computed property directly will break the observer functionality of the computed property.</em>
<br>
<br>
<hr>
<h2>Demo2: Changing a oneWay value on an observed property</h2>
<p>color1: ({{color4}}) + color2: ({{color5}}) = color3: ({{color6}})</p>
Change color1oneWay:
<button class="red" onclick={{action "changeColor" "color4oneWay" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color4oneWay" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color4oneWay" "blue"}}>blue</button>
<br>
<em>changing a property with a oneWay relationship to another property will not affect the original property (in this case, color1). so color3 will not be affected.</em>
<br>
<br>
Change color2:
<button class="red" onclick={{action "changeColor" "color5" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color5" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color5" "blue"}}>blue</button>
<br>
<em>changing color2 directly will affect the color3 computed value, but only if color3 has not been set directly.</em>
<br>
<br>
<hr>
<h2>Demo3: Changing an aliased value on an observed property</h2>
<p>color1: ({{color7}}) + color2: ({{color8}}) = color3: ({{color9}})</p>
Change color1alias:
<button class="red" onclick={{action "changeColor" "color7alias" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color7alias" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color7alias" "blue"}}>blue</button>
<br>
<em>changing a property that is aliased to another property will directly affect the original property (in this case, color1). so color3 will be affected.</em>
<br>
<br>
Change color2:
<button class="red" onclick={{action "changeColor" "color8" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color8" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color8" "blue"}}>blue</button>
<br>
<em>changing color2 directly will affect the color3 computed value, but only if color3 has not been set directly.</em>
<br>
<br>
<hr>
<h2>Demo4: Overwriting a property on a computed object</h2>
<p>color1: ({{colorObject.primary1}}) + color2: ({{colorObject.primary2}}) = color3: ({{colorObject.secondary}})</p>
Change color1:
<button class="red" onclick={{action "changeColor" "color10" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color10" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color10" "blue"}}>blue</button>
<br>
<em>changing color1 directly will affect the color3 computed value, but only if color3 has not been set directly.</em>
<br>
<br>
Change color2:
<button class="red" onclick={{action "changeColor" "color11" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColor" "color11" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColor" "color11" "blue"}}>blue</button>
<br>
<em>changing color2 directly will affect the color3 computed value, but only if color3 has not been set directly.</em>
<br>
<br>
Change "secondary" property on colorObject:
<button class="red" onclick={{action "changeColorObject" "red"}}>red</button>
<button class="yellow" onclick={{action "changeColorObject" "yellow"}}>yellow</button>
<button class="blue" onclick={{action "changeColorObject" "blue"}}>blue</button>
<br>
<em>changing a property on a returned object from a computed property directly will NOT break the observer functionality of the computed property.</em>
{
"version": "0.15.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.4.3",
"ember-template-compiler": "3.4.3",
"ember-testing": "3.4.3"
},
"addons": {
"ember-data": "3.4.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment