2016-06-23 10 views
0

JSのTOOLSを作成JavaScript動的オブジェクトクラス

角度1.5.xの& lodash 4.xの

QUESTION私はオブジェクトを作成するオブジェクトファクトリパターンを作成しようとしてい

/クラス 。以下の私の例では、コンテンツタイプのオブジェクトモデルを作成しています。私のスキルの限界を考えると、私は以下の記事の例をすべてのコンテンツタイプに対して複製しています。独自のプロトタイプを持つ動的オブジェクトクラスを作成する方法はJavaScriptにありますか?

現在のアプローチ

// constructor injection 
_Constructor.$inject = []; 
function _Constructor() { 
    function __constructor(data, keys) { 
     _.assign(this, _.pick(data, keys)); 
    } 
    return __constructor; 
} 

// one of many content type models 
Article.$inject = ['__constructor']; 
function Article(__constructor) { 
    function Article(data) { 
     var fillables = Object.freeze(['id','title','subtitle','body','body']); 
     __constructor.call(this, data, fillables); 
    } 

    Article.prototype = Object.create(__constructor.prototype); 
    Article.prototype.constructor = Article; 
    return Article; 
} 

IDEALアウトカム

私はユニークなコンテンツタイプのオブジェクトモデルを作成することを可能にするコンテンツタイプのモデル工場のパターンを作成します。擬似例:

var documentFillables = Object.freeze(['id', 'name', 'body']), 
    documentData = {id:1,name:'My Document', body: 'coolbody stuff'}, 
    Document = new ModelFactory('Document', documentData, documentFillables), 
    articleFillables = Object.freeze(['id', 'title', 'subtitle']), 
    articleData = {id:1,title:'My Article', subtitle: 'My Subtitle'}, 
    Article = new ModelFactory('Article', articleData, articleFillables); 

私はマージの周りプレイしたノート、拡張し、クローンと私はコードの冗長性のかなりの量および/または汎用オブジェクトすなわちで終わるオブジェクトを複製して拡張することができますががModelFactory()多くを持っていますが、 no Article()

答えて

1

すべてのドキュメントタイプに共通のサービス(コンストラクタ関数を返すファクトリ)を作成できます。

angular.extendを使用すると、渡されたデータでデフォルト値を拡張できます。

また、名前にも注意してください。 documentを使用して、ブラウザドキュメントオブジェクトとの名前の競合を回避してください。だから私はそれをmyDocumentと名づけた。

拡張ファクトリを作成するには、ファクトリ関数で依存関係注入を使用し、ベースを拡張します(例としてimageServiceのコードを参照)。

以下のデモをご覧になるか、jsfiddleをご覧ください。

angular.module('demoApp', []) 
 
    .factory('content', ContentService) 
 
    .factory('article', ContentService) 
 
    .factory('myDocument', ContentService) 
 
    .factory('myImage', imageService) 
 
    .controller('mainController', MainController); 
 

 
function MainController(article, myDocument, myImage) { 
 
    console.log(new article({ 
 
    title: 'Test' 
 
    })); 
 
    console.log(new myDocument({ 
 
    title: 'second' 
 
    })); 
 
    console.log(new myImage({ 
 
    title: 'image' 
 
    })); 
 
    var newImage = new myImage({ 
 
    title: 'placeholder img', 
 
    src: 'https://placehold.it/300' 
 
    }); 
 
    console.log(newImage); 
 

 
    this.newImage = newImage; 
 
} 
 

 
function generateUUID() { 
 
    var d = new Date().getTime(); 
 
    if (window.performance && typeof window.performance.now === "function") { 
 
    d += performance.now(); //use high-precision timer if available 
 
    } 
 
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { 
 
    var r = (d + Math.random() * 16) % 16 | 0; 
 
    d = Math.floor(d/16); 
 
    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); 
 
    }); 
 
    return uuid; 
 
} 
 

 
/* 
 
// base not really needed, just as example 
 
function base(options) { 
 
\t angular.extend(this, { 
 
     id: generateUUID(), 
 
     title: '', 
 
     subtitle: '', 
 
     body: '' 
 
    }, options); 
 
}*/ 
 

 
function ContentService() { 
 
    return function(options) { 
 
    //base.call(this, options); 
 
    angular.extend(this, { 
 
     id: generateUUID(), 
 
     title: '', 
 
     subtitle: '', 
 
     body: '' 
 
    }, options); 
 
    }; 
 
} 
 

 
function imageService(content, $window) { 
 

 
    return function(options) { 
 
    var contentFactory = new content(options); 
 

 
    angular.extend(contentFactory, { 
 
     example: function() { 
 
     $window.alert('extended service: ' + contentFactory.title); 
 
     } 
 
    }); 
 

 
    return contentFactory; 
 
    } 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="demoApp" ng-controller="mainController as ctrl"> 
 
    <h3> 
 
    click image to test extended content class 
 
    </h3> 
 
    <img ng-src="{{ctrl.newImage.src}}" ng-click="ctrl.newImage.example()" /> 
 
    <p> 
 
    {{ctrl.newImage.title}} 
 
    </p> 
 
</div>