How to do true MVVC in Typescript {N} app


I am struggling with how to properly architect an application using Typescript and NOT angular. So a page’s hierarchy should look like this:

- home.xml
- home.css
- home.ts
- home-model.ts

home-model.ts contains a class that extends observable like this:

export class HomeModel extends Observable {
    constructor() {

    public header_text: string = 'This Week';

In that class, I do not have access to the Page, therefore dont have access to any views within it to, for example, animate them. I think if I am following mvvc correctly though, all view manipulation should be done in home.ts. But here is where I am struggling:

Say I want to animate a view to pop up over my main view based on a tap, and operations that happen in that second overlay view will affect some observable properties. So say I wanted to change header_text. Here’s how I am doing it now, although it feels very wrong, and there are cases where my UI isnt noticing the changes to my observable class properties:

in home.ts:

export function loaded(args: EventData) {
    page = <Page>args.object;
    page.bindingContext = new HomeModel();
    page.bindingContext.set('editHeader', function() {
        page.bindingContext.set('header_text', 'Next Week');
            opacity: 1,
            duration: 1000

// then in my xml

<Button tap="{{editHeader}}" text="Change to Next Week" />

Thats not a real function in my app, but it illustrates my problem. I am doing some more complicated things like this:

export function loaded(args: EventData) {

    page.bindingContext.set('editFamily', function(args) {
        let families = page.bindingContext.get('families');
        let family = families.filter(item => ===[0];
        page.bindingContext.set('editingFamily', family);
        page.bindingContext.set('settingsTitle', 'Edit Family');
        page.getViewById('family_name').text = family.get('name');
        page.getViewById('family_email').text = family.get('email');

function showSettings(viewPath) {
    page.bindingContext.set('settingsShown', true);
    let deviceHeight = screen.mainScreen.heightDIPs;
    settingsContainer.translateY = deviceHeight + 30;
        translate: {x: 0, y: 0},
        duration: 300,
        curve: AnimationCurve.cubicBezier(0.1, 0.1, 0.1, 1)
    settingsOverlayContainer.opacity = 0;
        opacity: 1,
        duration: 100
    var container: StackLayout = page.getViewById('settings_view');
    let path = fs.knownFolders.currentApp().path;
    let component = builder.load(path + viewPath);

    let containerBounds = settingsContainer.ios.bounds;
    if (!blurView) {
        blurView = UIVisualEffectView.alloc().initWithEffect(UIBlurEffect.effectWithStyle(UIBlurEffectStyleLight));

        blurView.frame = {
            origin: { x: containerBounds.origin.x, y: containerBounds.origin.y - 20 },
            size: { width: containerBounds.size.width, height: containerBounds.size.height + 20 }
        blurView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

I could use some pointers on best practices for this sort thing. I am also calling services from a shared class that saves info to firebase.

This is my whole repo if you really want to dig in and give me some pointers:


@jen.looper any love?