Skip to content

Commit

Permalink
Moved decorators into another file and renamed base model to abstract…
Browse files Browse the repository at this point in the history
… model both in order to resolve load order issues. This will need to be resolved at another time.
  • Loading branch information
zakhenry committed Aug 10, 2015
1 parent b85d3c3 commit 699fed1
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 68 deletions.
42 changes: 25 additions & 17 deletions app/src/app/admin/articles/article/article.tpl.html
@@ -1,17 +1,25 @@
<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="Post">
<md-content class="md-padding" ui-view="post"></md-content>
</md-tab>
<md-tab label="Media">
<md-content class="md-padding" ui-view="media"></md-content>
</md-tab>
<md-tab label="Meta">
<md-content class="md-padding" ui-view="meta"></md-content>
</md-tab>
<md-tab label="Stats">
<md-content class="md-padding" ui-view="stats"></md-content>
</md-tab>
<md-tab label="History">
<md-content class="md-padding" ui-view="history"></md-content>
</md-tab>
</md-tabs>

<form novalidate name="articleForm" ng-submit="ArticleController.save()">

<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="Post">
<md-content class="md-padding" ui-view="post"></md-content>
</md-tab>
<md-tab label="Media">
<md-content class="md-padding" ui-view="media"></md-content>
</md-tab>
<md-tab label="Meta">
<md-content class="md-padding" ui-view="meta"></md-content>
</md-tab>
<md-tab label="Stats">
<md-content class="md-padding" ui-view="stats"></md-content>
</md-tab>
<md-tab label="History">
<md-content class="md-padding" ui-view="history"></md-content>
</md-tab>
</md-tabs>


<md-button class="md-primary md-raised" ng-disabled="articleForm.$invalid" type="submit">Save</md-button>

</form>
20 changes: 18 additions & 2 deletions app/src/app/admin/articles/article/article.ts
Expand Up @@ -78,8 +78,24 @@ namespace app.admin.articles.article {

export class ArticleController {

static $inject = ['article', '$stateParams'];
constructor(public article:common.models.Article, public $stateParams:IArticleStateParams) {
static $inject = ['article', '$stateParams', 'articleService', '$mdToast'];
constructor(public article:common.models.Article, public $stateParams:IArticleStateParams, private articleService:common.services.article.ArticleService, private $mdToast:ng.material.IToastService) {
}

/**
* Save the article
* @returns {any}
*/
public save(){

return this.articleService.saveArticle(this.article, this.$stateParams.newArticle)
.then(() => {
this.$mdToast.show({
hideDelay:2000,
position:'top',
template:'<md-toast>Article saved</md-toast>'
});
});
}

}
Expand Down
26 changes: 12 additions & 14 deletions app/src/app/admin/articles/article/post/post.tpl.html
@@ -1,41 +1,40 @@
<h2 ng-if="ArticleController.$stateParams.newArticle">Create</h2>
<h2 ng-if="!ArticleController.$stateParams.newArticle">Edit</h2>

<form novalidate name="postForm">

<md-input-container>
<label for="postFormTitle">Title</label>
<label for="articleFormTitle">Title</label>

<input id="postFormTitle" ng-model="ArticleController.article.title" name="title" type="text" ng-required="true">
<ng-messages for="postFormTitle.title.$error">
<input id="articleFormTitle" ng-model="ArticleController.article.title" name="title" type="text" ng-required="true">
<ng-messages for="articleFormTitle.title.$error">
<ng-message when="required">This is required.</ng-message>
</ng-messages>
</md-input-container>

<md-input-container>
<label for="postFormPermalink">Permalink</label>
<label for="articleFormPermalink">Permalink</label>

<input id="postFormPermalink" ng-model="ArticleController.article.permalink" name="permalink" type="text" ng-required="true" ng-change="ArticleController.updatePermalink()">
<ng-messages for="postFormTitle.permalink.$error">
<input id="articleFormPermalink" ng-model="ArticleController.article.permalink" name="permalink" type="text" ng-required="true" ng-change="ArticleController.updatePermalink()">
<ng-messages for="articleFormTitle.permalink.$error">
<ng-message when="required">This is required.</ng-message>
</ng-messages>
</md-input-container>


<md-input-container flex>
<label for="postFormContent">Content</label>
<label for="articleFormContent">Content</label>

<textarea id="postFormContent" ng-model="ArticleController.article.content" columns="1"></textarea>
<ng-messages for="postFormTitle.title.$error">
<textarea id="articleFormContent" ng-model="ArticleController.article.content" columns="1"></textarea>
<ng-messages for="articleFormTitle.title.$error">
<ng-message when="required">This is required.</ng-message>
</ng-messages>
</md-input-container>

<md-input-container flex>
<label for="postFormExcerpt">Excerpt</label>
<label for="articleFormExcerpt">Excerpt</label>

<textarea id="postFormExcerpt" ng-model="ArticleController.article.excerpt" columns="1" md-maxlength="140"></textarea>
<ng-messages for="postFormTitle.excerpt.$error">
<textarea id="articleFormExcerpt" ng-model="ArticleController.article.excerpt" columns="1" md-maxlength="140"></textarea>
<ng-messages for="articleFormTitle.excerpt.$error">
<ng-message when="maxlength">Maximum length is 140 chars (Like a tweet!)</ng-message>
</ng-messages>
</md-input-container>
Expand All @@ -49,4 +48,3 @@ <h2 ng-if="!ArticleController.$stateParams.newArticle">Edit</h2>
delete-hint="Press delete to remove tag"
secondary-placeholder="+Tag"></md-chips>

</form>
@@ -1,27 +1,25 @@
let seededChance = new Chance(1);
namespace common.decorators {

let data:any = {
uuid:seededChance.guid(),
string:seededChance.string(),
};
let seededChance = new Chance(1);

@common.models.changeAware
class TestModel extends common.models.Model {
public string;
public uuid;
let data:any = {
uuid:seededChance.guid(),
string:seededChance.string(),
};

constructor(data){
super(data);
_.assign(this, data);
}
}

(() => {
@changeAware
class TestModel extends common.models.AbstractModel {
public string;
public uuid;

constructor(data){
super(data);
_.assign(this, data);
}
}

describe('@changeAware decorator', () => {


it('should instantiate a new model', () => {

let model = new TestModel(data);
Expand All @@ -34,7 +32,7 @@ class TestModel extends common.models.Model {

let model = new TestModel(data);

expect((<common.models.IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.be.empty;
expect((<IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.be.empty;

});

Expand All @@ -44,7 +42,7 @@ class TestModel extends common.models.Model {

model.string = 'foo';

expect((<common.models.IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.include('string');
expect((<IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.include('string');

});

Expand All @@ -54,48 +52,47 @@ class TestModel extends common.models.Model {

model.string = 'foo';

(<common.models.IChangeAwareDecorator>model).resetChangedProperties();
(<IChangeAwareDecorator>model).resetChangedProperties();

expect((<common.models.IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.be.empty;
expect((<IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.be.empty;

});

it('should be able to retrieve the original unmodified object', () => {


let original = new TestModel(data);
let model = new TestModel(data);

model.string = 'foo'; //make a change

expect((<common.models.IChangeAwareDecorator>model).getOriginal()).to.deep.equal(original);
expect((<IChangeAwareDecorator>model).getOriginal()).to.deep.equal(original);

});

it ('should be able to retrieve the changed key-value map', () => {
it('should be able to retrieve the changed key-value map', () => {

let model = new TestModel(data);

model.string = 'foo'; //make a change

expect((<common.models.IChangeAwareDecorator>model).getChanged()).to.deep.equal({
expect((<IChangeAwareDecorator>model).getChanged()).to.deep.equal({
string: 'foo'
});

});

it ('should not mark a property as changed if it returns to it\'s original value', () => {
it('should not mark a property as changed if it returns to it\'s original value', () => {

let original = new TestModel(data);
let model = new TestModel(data);

model.string = 'foo'; //make a change
model.string = original.string; //change it back

expect((<common.models.IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.be.empty;
expect((<IChangeAwareDecorator>model).getChangedProperties()).to.be.instanceOf(Array).and.to.be.empty;

});

});

})();
}
@@ -1,9 +1,9 @@
namespace common.models {
namespace common.decorators {

export interface IChangeAwareDecorator{
getChangedProperties?():string[];
resetChangedProperties?():void;
getOriginal?():typeof Model;
getOriginal?():typeof common.models.AbstractModel;
getChanged?():{
[key:string]: any;
};
Expand Down
@@ -1,3 +1,4 @@
//note this file MUST be loaded before any depending classes @todo resolve model load order
namespace common.models {

export interface IModel{} //@todo add common methods/properties of a Model
Expand All @@ -6,7 +7,7 @@ namespace common.models {
(data:any):IModel;
}

export class Model implements IModel {
export class AbstractModel implements IModel {

constructor(data?:any) {
if (data){
Expand Down
6 changes: 4 additions & 2 deletions app/src/common/models/article/articleModel.ts
@@ -1,7 +1,7 @@
namespace common.models {

@changeAware
export class Article implements IModel{
@common.decorators.changeAware
export class Article extends AbstractModel{

public articleId:string;
public title:string;
Expand All @@ -12,6 +12,8 @@ namespace common.models {

constructor(data:any) {

super(data);

_.assign(this, data);

}
Expand Down
4 changes: 2 additions & 2 deletions app/src/common/models/user/userModel.ts
@@ -1,7 +1,7 @@
namespace common.models {

@changeAware
export class User extends Model implements global.IUserData {
@common.decorators.changeAware
export class User extends AbstractModel implements global.IUserData {

public static adminType = 'admin';
public static guestType = 'guest';
Expand Down
15 changes: 15 additions & 0 deletions app/src/common/services/article/articleService.ts
Expand Up @@ -60,6 +60,21 @@ namespace common.services.article {

}

/**
* Save the article
* @param article
* @param newArticle
* @returns {any}
*/
public saveArticle(article:common.models.Article, newArticle:boolean = false){

let method = newArticle? 'put' : 'patch';

return this.ngRestAdapter[method]('/articles/'+article.articleId, (<common.decorators.IChangeAwareDecorator>article).getChanged())
.then((res) => article);

}

}

angular.module(namespace, [])
Expand Down

0 comments on commit 699fed1

Please sign in to comment.