pertrai1 pertrai1 - 5 months ago 102
AngularJS Question

Angular 1.4 ES6 Class Directive

I am working on seeing if I can take a directive in 1.4 and trying to resemble a 1.5 component. I am using

bindToController
and
controllerAs
to use the controller in my directive instead of a separate controller. I have done this successfully with exporting as a function, but wanted to see if I could export as a class, and see if there is a good reason to do so. I am running into a
bindToController
error right now with the following code:

export default class recordingMenuComponent {
constructor(RecordingCtrl) {
'ngInject';
this.restrict = 'E',
this.scope = {},
this.templateUrl = '/partials/media/recording/recording-menu.html',
this.controller = RecordingCtrl,
this.controllerAs = 'record',
this.bindToController = {
video: '='
}
}

RecordingCtrl($log, $scope, $state, $timeout, RecordingService) {
'ngInject';
const record = this;
Object.assign(record, {
recentCalls: record.recentCalls,
startRecording() {
let video = {
accountId: $scope.accountId,
title: record.sipUrl
};

RecordingService
.recordVideoConference(video, record.sipUrl, record.sipPin, 0)
.then(result => {
video.id = result.id;
$timeout(() => $state.go('portal.video', {videoId: video.id}), 500);
}, error => $log.error('Error starting the recording conference: ', error));
},
getRecentCalls() {
RecordingService
.recentVideoConferenceCalls()
.then(result => {
record.recentCalls = result;
}, error => $log.error('There was an error in retrieving recent calls: ', error));
}
});
}

static recordingFactory() {
recordingMenuComponent.instance = new recordingMenuComponent();
return recordingMenuComponent.instance;
}
}


and then importing:

import angular from 'angular'
import recordingMenuComponent from './recordingMenuComponent'

angular.module('recordingModule', [])
.directive(recordingMenuComponent.name, recordingMenuComponent.recordingFactory);


There is some of the module that I have left out for brevity that did not have to do with trying to turn this directive into a component. Note that I am trying to not use the
.controller()
before the
.directive()
.

When I try to use this, I get this error:

angular.js:9490 Error: [$compile:noctrl] Cannot bind to controller without directive 'recordingMenuComponent's controller


I am not sure I am going on the right track or this is not the right road to be going on.

Thank you for any help.

Answer

You should implement RecordingCtrl as a class

const app = require('../app');

class RecordingCtrl {

    static $inject = ['$log', 'RecordingService'];
    constructor($log, recordingService) {
        this.$log = $log;
        this.recordingService = recordingService;
    }


    startRecording() {
        // . . .
    }

    recentCalls() {
        // . . . 
    }
}

// for ng15 component
const recordingMenu = {
     restrict: 'E',
     scope = {},
     templateUrl = '/partials/media/recording/recording-menu.html',
     controller = RecordingCtrl,
     controllerAs = 'record',
     bindToController = {
         video: '='
     }
}

app.component('recordingMenu', recordingMenu);

// or ng1.4 directive
function recordingMenu() {
    return {
        restrict: 'E',
        scope = {},
        templateUrl = '/partials/media/recording/recording-menu.html',
        controller = RecordingCtrl,
        controllerAs = 'record',
        bindToController = {
           video: '='
        }
     }
}

app.directive('recordingMenu', recordingMenu);

It does't make sense to implement a controller as a class method.

This means you will have two classes... unless you just want to make the Directive Definition Object factory a plain-old-function or a static method of your controller.

Comments