Both override and mixin a class - javascript

Is it possible to both override and mixin a class?
I tried applying the mixin inside the constructor, but it is not adding he properties/functions to the override.
I thought mixins were implicitly applied to the class referring to them?
Mixin
Ext.define('App.mixins.VTypes', {
//extend: 'Ext.mixin.Mixin',
timeTest : /^([1-9]|1[0-9]):([0-5][0-9])(\s[a|p]m)$/i,
time: function(v, field) { return this.timeTest.test(v); },
timeText: 'Not a valid time. Must be in the format "12:34 PM".',
timeMask: /[\d\s:amp]/i
});
Override
Ext.define('App.overrides.VTypes', {
override : 'Ext.form.field.VTypes',
mixins : {
vtypes : 'App.mixins.VTypes'
},
IPAddressTest : /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,
IPAddress: function(v) { return this.IPAddressTest.test(v); },
IPAddressText: 'Must be a numeric IP address, for eg: 111.1.1.1',
IPAddressMask: /[\d\.]/i,
constructor : function() {
Ext.apply(this, this.mixins.vtypes);
this.callParent(arguments);
}
});
Here's the Sencha Fiddle I am working on.

You can not apply a mixin to Ext.form.field.VTypes easily. In fact, your constructor never gets called (Take a look at the source code of Ext.form.field.VTypes). Additionally, Ext.form.field.VTypes is defined as a singleton.
The definition of Ext.form.field.VTypes looks very different to a class definition for e.g. a GridPanel. It behaves more like a pure JS "class" definition, thus your mixin gets never applied as it would for a "normal" ExtJS class.
Nevertheless, you can easily simulate a mixin behavior by your own:
var ip = {
IPAddressTest : /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,
IPAddress: function(v) { return this.IPAddressTest.test(v); },
IPAddressText: 'Must be a numeric IP address, for eg: 111.1.1.1',
IPAddressMask: /[\d\.]/i
};
var time = {
timeTest : /^([1-9]|1[0-9]):([0-5][0-9])(\s[a|p]m)$/i,
time: function(v, field) { return this.timeTest.test(v); },
timeText: 'Not a valid time. Must be in the format "12:34 PM".',
timeMask: /[\d\s:amp]/i
};
Ext.apply(Ext.form.field.VTypes, ip);
Ext.apply(Ext.form.field.VTypes, time);
Here, you spare the override and just apply the object definition to the Ext.form.field.VTypes singleton. I think, doing it that way is even more readable and understandable (but that's just my opinion).

Related

ExtJS config members with getter or setter only

How can I create config members with a getter or setter only but not both at the same time?
By default it creates both a getter and setter.
Ext.define('Myapp.myclass', {
config: {
conf1 : true, // Make this only have setter.
conf2 : false // Make this only have getter.
},
constructor: function(config) {
this.apply(config);
}
});
Configs actually create 4 helper methods, which are quite useful.
_config1 this is where the value gets saved
getConfig1 gets you the value
applyConfig1 allows you to check if the setter value is valid
updateConfig1 do some stuff to dom elements
setConfig1 call applyConfig1 and updateConfig1 if available and set the value to _config1. Usually you dont want to touch this, but use updateConfig1
If you do not want these then you have to do the work yourself, but you might not get bindables or other ExtJS out of the box functionality. For me it does not make a lot of sense not to use configs.
Ext.define('Myapp.myclass', {
_conf1: true, // Make this only have setter.
setConfig1: function(value) {
let oldValue = this._config1;
if(oldValue === value) return;
this._config1 = value;
},
_conf2: true, // Make this only have getter.
getConfig2: function() {
return this._config2;
}
});

Ember Controllers and "virtual" and/or "abstract" methods?

I am aware that JS isn't designed to handle inheritance per OOP "cleanly", but I wonder if Ember has a way to pull this off.
In Ember, I figure that Ember.ObjectController.extend({...}); is somewhat inheritance, but not completely - we surely can add our own properties and methods, hence the function .extend({...}), but we can't "override" a function that already exists. I wonder if there is such a workaround to this.
If I created a base controller, how would I define functions that I want child controllers to implement? I have the base controller (theory code only):
App.BaseController = Ember.ObjectController.extend({
// Methods meant for a child controller to implement
abstractMethod1: null,
abstractMethod2: null,
virtualMethod1: function(){
...
},
actions: {
execute: function(){
if(this.get("abstractMethod1"))
this.get("abstractMethod1")();
...
if(this.get("abstractMethod2")
var x = this.get("abstractMethod2")();
}
}
});
Then I have an implementing controller trying to override those functions:
App.ImplementingController = App.BaseController.extend({
/* How would I implement abstractMethod1 and abstractMethod2 here!?
For virtualMethod1, how would I call something like base.virtualMethod1()
or super.virtualMethod1()?
*/
});
I found myself creating a ton of controllers that have basically the same code, except for the name of the model and its properties. It would be nice to be able to pull of this scheme in Ember. What to do?
Actually Ember does that perfectly fine, you just don't override it and it hits the base implementation. Or you do override it and it blasts away the base implementation. (this is essentially how Mixins work as well, http://emberjs.com/api/classes/Ember.Mixin.html) And if you want to hit a base function, property etc, it's just accessed with this (it essentially smashes the two classes together, giving precedence to the extended class.
Base
App.BaseController = Ember.ObjectController.extend({
a:'Base',
b:'Base',
acomp: function(){
return 'Base';
}.property(),
bcomp: function(){
return 'Base';
}.property(),
e:function(){
return 'Base';
},
f:function(){
return 'Base';
}
});
Extended
App.IndexController = App.BaseController.extend({
b:'Index',
c:'Index',
bcomp: function(){
return 'Index';
}.property(),
f:function(){
return 'Index';
},
actions:{
foo:function(){
console.log(this.e());
console.log(this.f());
}
}
});
What it looks like after Ember Combines them
App.IndexController....
a:'Base'
b:'Index',
c:'Index',
acomp: function(){
return 'Base';
}.property(),
bcomp: function(){
return 'Index';
}.property(),
e:function(){
return 'Base';
},
f:function(){
return 'Index';
},
actions:{
foo:function(){
console.log(this.e());
console.log(this.f());
}
}
});
http://emberjs.jsbin.com/wuhuleje/2/edit

React.js 2-way bindings: two-levels deep path in valueLink

My state is:
[
{type: "translateX", x: 10},
{type: "scaleX", x: 1.2}
]
I’m using Two-Way Binding Helpers and I can’t provide a valid key string for linkState:
this.state.map(function(item, i) {
return <div><input valueLink={this.linkState( ??? )}></div>
}
Would be nice if this.linkState accepted some query syntax, such as "0.type" to retrieve "translateX" from my example.
Are there any workarounds?
I wrote DeepLinkState mixin which is a drop-in replacement for React.addons.LinkedStateMixin. Usage example:
this.state.map(function(item, i) {
return <div><input valueLink={this.linkState([i, "x"])}></div>
}
linkState("0.x") is also acceptable syntax.
Edit:
I realized that deep-path for LinkedState is pretty cool so I try to implement it.
The code: https://gist.github.com/tungd/8367229
Usage: http://jsfiddle.net/uHm6k/3/
As the document stated, LinkedState is a wrapper around onChange/setState and meant for simple case. You can always write the full onChange/setState to achieve what you want. If you really want to stick with LinkedState, you can use the non mixin version, for example:
getInitialState: function() {
return { values: [
{ type: "translateX", x: 10 },
{ type: "scaleX", x: 1.2 }
]}
},
handleTypeChange: function(i, value) {
this.state.values[i].type = value
this.setState({ values: this.state.values })
},
render: function() {
...
this.state.values.map(function(item, i) {
var typeLink = {
value: this.state.values[i].type,
requestChange: this.handleTypeChange.bind(null, i)
}
return <div><input valueLink={typeLink}/></div>
}, this)
...
}
Here is working JSFiddle: http://jsfiddle.net/srbGL/
You can implement your own mixin if the base mixin doesn't satisfy you.
See how this mixin is implemented:
var LinkedStateMixin = {
/**
* Create a ReactLink that's linked to part of this component's state. The
* ReactLink will have the current value of this.state[key] and will call
* setState() when a change is requested.
*
* #param {string} key state key to update. Note: you may want to use keyOf()
* if you're using Google Closure Compiler advanced mode.
* #return {ReactLink} ReactLink instance linking to the state.
*/
linkState: function(key) {
return new ReactLink(
this.state[key],
ReactStateSetters.createStateKeySetter(this, key)
);
}
};
/**
* #param {*} value current value of the link
* #param {function} requestChange callback to request a change
*/
function ReactLink(value, requestChange) {
this.value = value;
this.requestChange = requestChange;
}
https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/addons/link/LinkedStateMixin.js
https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/addons/link/ReactLink.js
So you can easily try to write your own linkState function based on the above.
linkState: function(key,key2) {
return new ReactLink(
this.state[key][key2],
function(newValue) {
this.state[key][key2] = newValue;
}
);
}
Notice that I didn't use the ReactStateSetters.createStateKeySetter(this, key).
https://github.com/facebook/react/blob/fc73bf0a0abf739a9a8e6b1a5197dab113e76f27/src/core/ReactStateSetters.js
By looking at the source code again you can find out this method doesn't do so much except it creates a function and does little caching optimizations:
function createStateKeySetter(component, key) {
// Partial state is allocated outside of the function closure so it can be
// reused with every call, avoiding memory allocation when this function
// is called.
var partialState = {};
return function stateKeySetter(value) {
partialState[key] = value;
component.setState(partialState);
};
}
So you should definitely try to write your own mixin.
This can be very useful if you have in your state a complex object and you want to modify it through the object API.
I do it without using value-link addon.
Here is a demo: http://wingspan.github.io/wingspan-forms/examples/form-twins/
The secret sauce is to only define one onChange function:
onChange: function (path, /* more paths,*/ value) {
// clone the prior state
// traverse the tree by the paths and assign the value
this.setState(nextState);
}
use it like this:
<input
value={this.state['forms']['0']['firstName']}
onChange={_.partial(this.onChange, 'forms', '0', 'firstName')} />
If you have many (value, onChange) pairs that you have to pass around everywhere, it might make sense to define an abstraction around this similar to ReactLink, but I personally got pretty far without using ReactLink.
My colleagues and I recently open sourced wingspan-forms, a React library that helps with with deeply nested state. We leverage this approach heavily. You can see more example demos with linked state on the github page.
I wrote a blogpost about it: http://blog.sendsonar.com/2015/08/04/angular-like-deep-path-data-bindings-in-react/
But basically I created a new component that would accept the 'state' of parent and a deep path, so you don't have to write extra code.
<MagicInput binding={[this, 'account.owner.email']} />
There's a JSFiddle too so you can play with it
Here's the tutorial explaining how to handle things like this.
State and Forms in React, Part 3: Handling the Complex State
TL;DR:
0) Don't use standard links. Use these.
1) Change your state to look like this:
collection : [
{type: "translateX", x: 10},
{type: "scaleX", x: 1.2}
]
2) Take link to the collection:
var collectionLink = Link.state( this, 'collection' );
3) Iterate through the links to its elements:
collectionLink.map(function( itemLink, i ) {
return <div><input valueLink={itemLink}></div>
})
I took a different approach which does not employ mixins and does not automatically mutate the state
See github.com/mcmlxxxviii/react-value-link

Accessing object literals in Javascript

This code is an example from Marionette:
AppLayout = Backbone.Marionette.Layout.extend(
{
template: "#layout-template",
regions:
{
menu: "#menu",
content: "#content"
}
});
var layout = new AppLayout();
layout.menu.show(new MenuView());
layout.content.show(new MainContentView());
The last two lines confuse me. Why doesn't it read:
layout.regions.menu.show(new MenuView());
layout.regions.content.show(new MainContentView());
Can someone please explain why layout.menu works and layout.regions.menu doesn't?
What if I wanted to access template? Wouldn't that be layout.template? template and regions are at the same depth inside layout.
Here is the constructor function from the marionette code:
// Ensure the regions are avialable when the `initialize` method
// is called.
constructor: function () {
this._firstRender = true;
this.initializeRegions();
var args = Array.prototype.slice.apply(arguments);
Marionette.ItemView.apply(this, args);
},
I believe it was implemented that way because 'layout.menu' is shorter and simpler than 'layout.regions.menu'. Looks like you expected the literal "#menu" to be replaced with a region manager object.
The options you passed in when creating the view, including the template, can be found in layout.options. So in your case layout.options.template should equal '#layout-template', and the regions definition hash would be at layout.options.regions... still the same level.
Unless there is more to the example then you are showing like the Backbone.Marionette.Layout methods, then its not accessing regions.menu like you think it is.
With just the code you have provided the code above is actually creating a menu attribute, which then has a show attribute so your layout object would actually look like this:
layout {
menu : {
show : new MenuView
},
content : {
show : new MainContentView
},
template: "#layout-template",
regions:
{
menu: "#menu",
content: "#content"
}
}
In javascript the (dot) operator can be used to access a property of an attribute or if no property with that name exists then it will create that property.
I'm not familiar with the backbone.js framework but my guess is that they provide for skipping part of the property lookup chain. which means that the above would end up producing this as your layout object:
layout {
template: "#layout-template",
regions:
{
menu : {
show : new MenuView
},
content : {
show : new MainContentView
}
}
}
But again that's just a guess on my part since I don't use backbone.
You can learn more about the object model and how it works with inheritance right here.

Making objects observable

I've been looking into JavaScript frameworks such as Angular and Meteor lately, and I was wondering how they know when an object property has changed so that they could update the DOM.
I was a bit surprised that Angular used plain old JS objects rather than requiring you to call some kind of getter/setter so that it could hook in and do the necessary updates. My understanding is that they just poll the objects regularly for changes.
But with the advent of getters and setters in JS 1.8.5, we can do better than that, can't we?
As a little proof-of-concept, I put together this script:
(Edit: updated code to add dependent-property/method support)
function dependentProperty(callback, deps) {
callback.__dependencies__ = deps;
return callback;
}
var person = {
firstName: 'Ryan',
lastName: 'Gosling',
fullName: dependentProperty(function() {
return person.firstName + ' ' + person.lastName;
}, ['firstName','lastName'])
};
function observable(obj) {
if (!obj.__properties__) Object.defineProperty(obj, '__properties__', {
__proto__: null,
configurable: false,
enumerable: false,
value: {},
writable: false
});
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
if(!obj.__properties__[prop]) obj.__properties__[prop] = {
value: null,
dependents: {},
listeners: []
};
if(obj[prop].__dependencies__) {
for(var i=0; i<obj[prop].__dependencies__.length; ++i) {
obj.__properties__[obj[prop].__dependencies__[i]].dependents[prop] = true;
}
delete obj[prop].__dependencies__;
}
obj.__properties__[prop].value = obj[prop];
delete obj[prop];
(function (prop) {
Object.defineProperty(obj, prop, {
get: function () {
return obj.__properties__[prop].value;
},
set: function (newValue) {
var oldValue = obj.__properties__[prop].value;
if(oldValue !== newValue) {
var oldDepValues = {};
for(var dep in obj.__properties__[prop].dependents) {
if(obj.__properties__[prop].dependents.hasOwnProperty(dep)) {
oldDepValues[dep] = obj.__properties__[dep].value();
}
}
obj.__properties__[prop].value = newValue;
for(var i=0; i<obj.__properties__[prop].listeners.length; ++i) {
obj.__properties__[prop].listeners[i](oldValue, newValue);
}
for(dep in obj.__properties__[prop].dependents) {
if(obj.__properties__[prop].dependents.hasOwnProperty(dep)) {
var newDepValue = obj.__properties__[dep].value();
for(i=0; i<obj.__properties__[dep].listeners.length; ++i) {
obj.__properties__[dep].listeners[i](oldDepValues[dep], newDepValue);
}
}
}
}
}
});
})(prop);
}
}
return obj;
}
function listen(obj, prop, callback) {
if(!obj.__properties__) throw 'object is not observable';
obj.__properties__[prop].listeners.push(callback);
}
observable(person);
listen(person, 'fullName', function(oldValue, newValue) {
console.log('Name changed from "'+oldValue+'" to "'+newValue+'"');
});
person.lastName = 'Reynolds';
Which logs:
Name changed from "Ryan Gosling" to "Ryan Reynolds"
The only problem I see is with defining methods such as fullName() on the person object which would depend on the other two properties. This requires a little extra markup on the object to allow developers to specify the dependency.
Other than that, are there any downsides to this approach?
JsFiddle
advent of getters and setters in JS 1.8.5 - are there any downsides to this approach?
You don't capture any property changes apart from the observed ones. Sure, this is enough for modeled entity objects, and for anything else we could use Proxies.
It's limited to browsers that support getters/setters, and maybe even proxies. But hey, who does care about outdated browsers? :-) And in restricted environments (Node.js) this doesn't hold at all.
Accessor properties (with getter and setter) are much slower than real get/set methods. Of course I don't expect them to be used in critical sections, and they can make code looking much fancier. Yet you need to keep that in the back of your mind. Also, the fancy-looking code can lead to misconceptions - normally you would expect property assignment/accessing to be a short (O(1)) operation, while with getters/setters there might be a lot of more happening. You will need to care not forgetting that, and the use of actual methods could help.
So if we know what we are doing, yes, we can do better.
Still, there is one huge point we need to remember: the synchronity/asynchronity (also have a look at this excellent answer). Angular's dirty checking allows you to change a bunch of properties at once, before the event fires in the next event loop turn. This helps to avoid (the propagation of) semantically invalid states.
Yet I see the synchronous getters/setters as a chance as well. They do allow us to declare the dependencies between properties and define the valid states by this. It will automatically ensure the correctness of the model, while we only have to change one property at a time (instead of changing firstName and fullName all the time, firstName is enough). Nevertheless, during dependency resolving that might not hold true so we need to care about it.
So, the listeners that are not related to the dependencies management should be fired asynchronous. Just setImmediate their loop.

Categories