OOP
Pattern 1 (Object Based): is a singleton. If you only need one such object, it's just fine.
var mouseDiff = {
"startPoint" : {"x" :0, "y" : 0},
"hypotenuse" : function(a,b) {
// do something
},
"init" : function(){
// do something
}
}
mouseDiff.init();
Pattern 2 (Most traditional as far as I know): builds new objects, and takes advantage of the prototype object so that when a new MouseDiff object is created, it will not create new copies of the functions (which are themselves data in JavaScript).
function MouseDiff() {
this.startPoint = {"x" :0, "y" : 0}; //private variable
}
MouseDiff.prototype.hypotenuse = function(a,b) {
// do something
}
MouseDiff.prototype.init = function() {
// do something
}
var myMouse = new MouseDiff;
myMouse.init();
Pattern 3 (Making use of closure): requires more memory in comparison to a regular singleton but it offers static privacy.
var MouseDiff2 = (function() {
var _startPoint = {"x" :0, "y" : 0}; //private var
var _hypotenuse = function(a,b) { //private method
// do something
};
return {
hypotenuse: _hypotenuse, //exposed private method to public
init : function(){ // do something } //public method
}; }());
MouseDiff2.init();
combination of the constructor (pattern 2) and closure (pattern 3): used in TypeScript (Microsoft)
var MouseDiff = (function () {
var aStaticVariable = 'Woohoo!';
// And if you really need 100% truly private instance variables which are not methods and which can be shared between methods (and don't mind the rather big hassle they require),
// see http://brettz9.blogspot.com/search?q=relator
// (see also the new plans for a Map/WeakMap in ECMAScript)
function _APrivateStaticMethod () {
alert(aStaticVariable);
}
// An instance method meant to be called on the // particular object as via ".call(this)" below
function _APrivateInstanceMethod () {
alert(this.startPoint.x);
}
// Begin Constructor
function MouseDiff() {
this.startPoint = {"x" :0, "y" : 0}; // private var
}
MouseDiff.prototype.hypotenuse = function(a,b) {
// do something
};
MouseDiff.prototype.init = function() {
// do something
_APrivateStaticMethod(); // alerts 'Woohoo!'
_APrivateInstanceMethod.call(this); // alerts 0 (but if not called with this, _APrivateInstanceMethod's internal "this" will refer (potentially dangerously) to the global object, as in the window in the browser unless this class was defined within 'strict' mode in which case "this" would be undefined)
};
return MouseDiff;
}());
var myMouse = new MouseDiff;
myMouse.init();
Developers please read this:
.JSX https://jsx.github.io/ (JSX is a statically-typed, object-oriented programming language designed to run on modern web browsers.)
if you really want Standard ECMA-262 5.1 Edition / June 2011
TypeScript
basically it is a hinting system for IDE
in object (class) you can specify what properties(functions) will be exposed and what hidden for IDE when you accessing this object as instance
class Book{
private var state=”open”
var pages=20 //considered as public
}
var book = new Book();
book.pages // will be given in hint but not variable state
as well it support extends and interface implementation
if you have array of Book
books:Book[ ];
books[2].state ; //will be given as hint
if you specify item type in function parameters
function addItem(item:Book){
}
passing any other objects rather than “Book” will be highlighted as Error
MVC
Dojo Descriptor
---------------------------------------
-------------------------------------------------
Flux Architecture with React MVC TODO
More examples of TODO https://github.com/tastejs/todomvc/tree/master/examples
Dojo Toolkit interest for back end ompressed (41KB, gzipped)
Angular, React, Ember.js, Backbone.js
var Timer = React.createClass({
getInitialState: function() {
return {secondsElapsed: 0};
},
tick: function() {
this.setState({secondsElapsed: this.state.secondsElapsed + 1});
},
componentDidMount: function() {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function() {
clearInterval(this.interval);
},
render: function() {
return (
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>
);
}
});
React.render(<Timer />, mountNode);
Backbone.js http://backbonetutorials.com/what-is-a-view/
<script type="text/template" id="search_template">
<label>Search</label>
<input type="text" id="search_input" />
<input type="button" id="search_button" value="Search" />
</script>
<div id="search_container"></div>
<script type="text/javascript">
<label>Search</label>
<input type="text" id="search_input" />
<input type="button" id="search_button" value="Search" />
</script>
<div id="search_container"></div>
<script type="text/javascript">
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
var template = _.template( $("#search_template").html(), {} );
this.$el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</script>
initialize: function(){
this.render();
},
render: function(){
var template = _.template( $("#search_template").html(), {} );
this.$el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</script>
Angular.js
<html ng-app="phonecatApp">
<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
<ul>
<li ng-repeat="phone in phones">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
</body>
</html>
<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
<ul>
<li ng-repeat="phone in phones">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
</body>
</html>
controllers.js
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', function ($scope) {
$scope.phones = [
{'name': 'Nexus S',
'snippet': 'Fast just got faster with Nexus S.'},
{'name': 'Motorola XOOM™ with Wi-Fi',
'snippet': 'The Next, Next Generation tablet.'},
{'name': 'MOTOROLA XOOM™',
'snippet': 'The Next, Next Generation tablet.'}
];
});
phonecatApp.controller('PhoneListCtrl', function ($scope) {
$scope.phones = [
{'name': 'Nexus S',
'snippet': 'Fast just got faster with Nexus S.'},
{'name': 'Motorola XOOM™ with Wi-Fi',
'snippet': 'The Next, Next Generation tablet.'},
{'name': 'MOTOROLA XOOM™',
'snippet': 'The Next, Next Generation tablet.'}
];
});
React docs
Components
build the component into a single Javascript and single CSS file.
Modules
Module is more logical, for example: module Finance, module HR, module Manufacturing... in ERP system. On the other hand, component is more physical. In software, it can be a dll, ocx, exe,..
AMD (Asynchronous Module Definition)
The two key concepts you need to be aware of here are the idea of a define method for facilitating module definition and a require method for handling dependency loading.
- define(
- module_id /*optional*/,
- [dependencies] /*optional*/,
- definition function /*function for instantiating the module or object*/
- );
Understanding AMD: define()
- // A module_id (myModule) is used here for demonstration purposes only
- define('myModule',
- ['foo', 'bar'],
- // module definition function
- // dependencies (foo and bar) are mapped to function parameters
- function ( foo, bar ) {
- // return a value that defines the module export
- // (i.e the functionality we want to expose for consumption)
- // create your module here
- var myModule = {
- doStuff:function(){
- console.log('Yay! Stuff');
- }
- }
- return myModule;
- });
- // An alternative example could be..
- define('myModule',
- ['math', 'graph'],
- function ( math, graph ) {
- // Note that this is a slightly different pattern
- // With AMD, it's possible to define modules in a few
- // different ways due as it's relatively flexible with
- // certain aspects of the syntax
- return {
- plot: function(x, y){
- return graph.drawPie(math.randomGrid(x,y));
- }
- }
- };
- });
Understanding AMD: plugins
The following is an example of defining an AMD-compatible plugin:
- // With AMD, it's possible to load in assets of almost any kind
- // including text-files and HTML. This enables us to have template
- // dependencies which can be used to skin components either on
- // page-load or dynamically.
- define(['./templates', 'text!./template.md','css!./template.css'],
- function( templates, template ){
- console.log(templates);
- // do some fun template stuff here.
- }
- });
we are not using Deferred now but may in future
Modules With Deferred Dependencies
- // This could be compatible with jQuery's Deferred implementation,
- // futures.js (slightly different syntax) or any one of a number
- // of other implementations
- define(['lib/Deferred'], function( Deferred ){
- var defer = new Deferred();
- require(['lib/templates/?index.html','lib/data/?stats'],
- function( template, data ){
- defer.resolve({ template: template, data:data });
- }
- );
- return defer.promise();
- });
Flux
Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with a React view, the view propagates an action through a central dispatcher, to the various stores that hold the application's data and business logic, which updates all of the views that are affected.
Central dispatcher
Actions https://github.com/facebook/flux/blob/master/examples/flux-todomvc/js/actions/TodoActions.js
Event Emitter (Business Logic)
No comments:
Post a Comment