Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract class controller declaration from component declaration #144

Open
aaronte opened this issue Dec 21, 2016 · 4 comments
Open

Extract class controller declaration from component declaration #144

aaronte opened this issue Dec 21, 2016 · 4 comments

Comments

@aaronte
Copy link

aaronte commented Dec 21, 2016

Hey, currently the x.component.js is declared as following where the controller is declared inline with the component declaration:

/* ----- todo/todo-form/todo-form.component.js ----- */
import templateUrl from './todo-form.html';

export const TodoFormComponent = {
    bindings: {
        todo: '<',
        onAddTodo: '&'
    },
    templateUrl,
    controller: class TodoFormComponent {
        constructor(EventEmitter) {
            'ngInject';
            this.EventEmitter = EventEmitter;
        }

        $onChanges(changes) {
            if (changes.todo) {
                this.todo = Object.assign({}, this.todo);
            }
        }

        onSubmit() {
            if (!this.todo.title) {
                return;
            }
            // with EventEmitter wrapper
            this.onAddTodo(
                this.EventEmitter({
                    todo: this.todo
                })
            );
            // without EventEmitter wrapper
            this.onAddTodo({
                $event: {
                    todo: this.todo
                }
            });
        }
    }
};

I was wondering if there's a reason why you chose to do it inline instead of declaring it first before using it like the following:

/* ----- todo/todo-form/todo-form.component.js ----- */
import templateUrl from './todo-form.html';

class TodoFormComponent {
    constructor(EventEmitter) {
        'ngInject';
        this.EventEmitter = EventEmitter;
    }

    $onChanges(changes) {
        if (changes.todo) {
            this.todo = Object.assign({}, this.todo);
        }
    }

    onSubmit() {
        if (!this.todo.title) {
            return;
        }
        // with EventEmitter wrapper
        this.onAddTodo(
            this.EventEmitter({
                todo: this.todo
            })
        );
        // without EventEmitter wrapper
        this.onAddTodo({
            $event: {
                todo: this.todo
            }
        });
    }
}

export const TodoFormComponent = {
    bindings: {
        todo: '<',
        onAddTodo: '&'
    },
    templateUrl,
    controller: TodoFormComponent
};

I think this makes it more readable and lessens indention? Thoughts?

@ryepup
Copy link

ryepup commented Jul 31, 2017

I like this adjustment too, the only issue with what's written above is re-using the name TodoFormComponent to mean two different things:

  • the controller for the component
  • the component definition itself

This is also tripping up the eslint no-redeclare rule.

This issue has been open for awhile, have you had any other positive or negative experience using this pattern in your application?

@dima716
Copy link

dima716 commented Jul 31, 2017

I would suggest to extract controller in different file and then import it as
import controller from './todo-form.controller';.

You can see an example here

@aaronte
Copy link
Author

aaronte commented Jul 31, 2017

@ryepup Woops. Made a typo. class and component variables should be different name. This is the pattern I have been using for my application so far and haven't had any problems:

import templateUrl from './todo-form.html';

class TodoForm {
    constructor(EventEmitter) {
        'ngInject';
        this.EventEmitter = EventEmitter;
    }
}

export const TodoFormComponent = {
    bindings: {
        todo: '<',
        onAddTodo: '&'
    },
    templateUrl,
    controller: TodoForm
};

@ryepup
Copy link

ryepup commented Aug 6, 2017

good to hear these divergences from the style guide are working out. We're looking to adopt this styleguide at work and trying to figure which bits are the MUSTs and which are the SHOULDs.

@aaronte it's not just a typo in this issue, the official docs (e.g. https://github.com/toddmotto/angularjs-styleguide/blame/master/README.md#L331)

export const TodoComponent = {
  templateUrl,
  controller: class TodoComponent {}
}

@dima716 that looks pretty good to me, although the guide recommends dropping the name "controller".

I think we'll probably try leaving the controller class in the same file as the component like you're suggesting, and pull it into another file if it gets too big. Although controllers aren't supposed to get big, so...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants