Enyo 2.7 and Angular2

Hi all. I'm trying to get Enyo 2.7 working with Angular2, specifically Model/RelationalModel/Collection.

What I'm doing is creating an Angular2 class that extends Model (and RelationalModel and Collection). For the most part, I've gotten it working. Unfortunately, when it adds to the Store, it uses the prototype name (e.g., enyo.Model) rather than the name given via Angular2 class upon construction. Example of code in typescript is below.

Any thoughts on how I could get the data layer of Enyo working with Angular2?

Thanks,
Cage

import {BaseRelationalModel} from './base-relationalmodel';
import {ORInfoModel} from './orinfo-model';

export class CaseModel extends BaseRelationalModel{

    url="http://localhosts/api/cases.json",
    source="orrms",
    primaryKey = "orrmscaseid",
    relations = [
        {
            key: 'orinfo',
            type: 'toOne',
            model: ORInfoModel,
            isOwner: true,
            includeInJSON: true,
            inverseKey: 'orcases',
            inverseType: 'toMany',
            create:true,
            parse:true
        }
    ],

    attributes={
        orrmscaseid: null,
        hospitalcaseid: null,
        surgdate: null,

        orid: null,
        orinfo: {},
        serviceid: null,

        scheduledprocedureinfo: {},
        actualprocedureinfo: {},
        operation:"",

        asa:null,
        urgency:"",
        cancelled:false,
        addon:false,
        casetype: null,

        surgattg: "",
        surgres: null,

        patid: null,
        patinfo: null,

        patcaseinfo: null,

        orcasetimes: {},
        staffbyorcase: [],

        deleted: false,
        datetimeinserted: null,
        datetimemodified: null,
        userinserting:null,
        usermodifying:null
    },

    constructor(attrs:string, props:string, opts:string){
        CaseModel.prototype.primaryKey = "orrmscaseid";
        super(attrs, props, opts);
    }
}



import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/from';
import 'rxjs/add/operator/map';
import * as Store from 'enyo/src/Store';
import * as Model from 'enyo/src/Model';
import * as utils from 'enyo/src/utils';

@Injectable()
export abstract class BaseRelationalModel extends Model{

    constructor(attrs:string, props:string, opts:string, http:Http){
        this.http = http;
        this.store = Store;
        super(attrs, props, opts);
    },

    fetch(opts) {

        var data = this.http.get(this.url)
                .map(res => res.json())
                .map(res => this.parse(res));
        return data;
    }
}

Comments

  • It looks like there might be some cruft in enyo/Store that is defaulting to using kindName rather than the prototype of the kind. Maybe @theryanjduffy can take a quick look at this and offer some insight.

    The code in Store looks like it should work OK so long as you set your kindName properly.

    I'm super curious what you're up to with all that!
  • I think @RoySutton is on the right track. I'd expect adding a kindName property to your prototypes matching its name would do the trick.
  • I think @RoySutton is on the right track. I'd expect adding a kindName property to your prototypes matching its name would do the trick.
  • Hmm, I tried adding kindName and unfortunately, it still adds to enyo.Model.

    @RoySutton : in Store.add(), it is referencing ctor.prototype.kindName, which i think is why it's getting enyo.Model. It seems to be referring to the parent's kindName rather than its own.
  • Also, if I change the prototype's kindName, won't it change the kindName for all the derived Models?
  • Did you create a new model kind to create your models from? Or just create an enyo.Model and modify its instance?
  • I created a Angular2 BaseModel component that extends enyo.Model. Then I created different Angular2 models that extend BaseModel. Collection.add adds these derived models. I don't know if Angular2 is using the same enyo.Model or creating different ones. How could I find out?
  • edited March 2016
    So I finally got it to work. Originally, I went down the route of CustomizedModelComponent / CustomizedCollectionComponent extending BaseModelComponent / BaseCollectionComponent extending enyo.Model / enyo.Collection (as shown above). The rationale was that the Angular2 BaseCompoent would do the job of returning Observables/Promises as required by Angular2. However, I was not able to get the constructors created correctly with the multiple inheritance and this was resulting in issues with enyo.Store, as noted above.

    Now, I am just directly importing and using my customized enyo models / collections in the Angular2 View Components. I created a DataService (HttpService) that accepts my customized child enyo model/collection and uses that to determine the URL to call. I might convert from using the Angular2 way for Ajax calls to the enyo.Collection.fetch / enyo.Source version in future but, for now, the Angular2 way is easier. I like its Subscribe method that allows auto updates from data source.

    @RoySutton : To answer your original question as to what I'm trying to accomplish with Angular2 / enyo2 integration:

    1. Trying to re-use my existing Enyo code, especially the relational data modeling in Enyo since I haven't found a great relational data modeling layer for Angular2 yet
    2. Using Ionic2 for its HTML templates, rich widget set, and native mobile integration. Ionic2 is integrated with Angular2.
    3. Using some Enyo components that don't exist in Ionic2 yet (e.g., a good progress bar component).

    Now that I've gotten the above to work, things are moving quickly! Ionic2 has made it much easier to develop the UI because of its HTML templating system.

    Next, I'm going to experiment with integrating DataList vs Ionic2 Lists to compare performance between the two! :smile:
    
    
    //case-model.js
    var
        kind = require('enyo/kind'),
        Model = require('enyo/Model')
    
    module.exports = kind({
        name:"CaseModel",
        kind: Model,
        source:"orrms",
        url:"http://localhost/apiv1/orcases.json",
        primaryKey: "id",
        attributes:{
            id: null,
            caseid: null,
            surgdate: null,
    
            deleted: false,
            datetimeinserted: null,
            datetimemodified: null,
            userinserting:null,
            usermodifying:null
        }
    });
    
    //case-collection.js
    var
        kind = require('enyo/kind'),
        platform = require('enyo/platform'),
        Collection = require('enyo/Collection'),
        CaseModel = require('./case-model');
    
    module.exports = kind({
        name:"CaseCollection",
        kind:Collection,
        model: CaseModel,
        source:"orrms",
        url:"http://localhost/apiv1/",
        readOnly:true,
        getUrl:function(opts){
            return (this.url + "/" + "orcases.json");
        },
        params:{surgDate:"2016/2/3", orid:"110,111,112,114"}
    });
    
    //home.js View
    import {Page} from 'ionic/ionic';
    import {CaseItem} from "./caseitem";
    import {ProgressBarComponent} from '../spinner/progress-bar';
    import {Observable} from 'rxjs/Rx';
    import {DataService} from '../../providers/data-service';
    import * as CaseCollection from '../../models/case-collection';
    
    @Page({
        templateUrl: 'build/pages/cases/home.html',
        providers: [DataService, CaseCollection],
        directives: [CaseItem, ProgressBarComponent]
    })
    
    export class Page0 {
        caseCollection:CaseCollection;
        isRequesting:Boolean;
        progressBar:ProgressBarComponent;
    
        constructor(private _dataService: DataService, public caseCollection:CaseCollection) {
            this.caseCollection = caseCollection;
            this.isRequesting = true;
            this._dataService
                .setURL(this.caseCollection.getUrl())
                .getAll()
                .subscribe((data) => this.caseCollection.add(data),
                    error => console.log(error),
                    () => {
                        console.log('Get all caseCollection complete', this.caseCollection);
                                this.stopRefreshing();
                    });
        }
    
        private stopRefreshing() {
            this.isRequesting = false;
        }
    
    }
    
    //data-service.js
    // available upon request
    
    
Sign In or Register to comment.