ExtJS Controllers Interraction

108 Views Asked by At

apologies if it's not termed correctly, development isn't my first language :)

I'm trying to add functionality to an extjs web application called Traccar (a web based tracking platform).

For anyone familiar with the application, what I'm trying to do is add a "quick report" button to the devices section, so that you can click a device, click the button and it will expand the reports section and pre-select the report type as trips, device as the selected device and click show.

From a technical perspective, I've achived some of this. I believe that there are two view controllers that I need to be concerned about - "DevicesController.js" (https://github.com/traccar/traccar-web/blob/9e1c0b44189136ec6abf05720c698027a689fa08/web/app/view/edit/DevicesController.js) and "ReportsController.js" (https://github.com/traccar/traccar-web/blob/9e1c0b44189136ec6abf05720c698027a689fa08/web/app/view/ReportController.js)

I've worked out how to expand the reports section at the bottom of the screen (that was fairly easy):

onQuickReportClick: function() {

  Ext.getCmp('reportViewPanel').expand(true);

},

I've been trying to call across to the reports controller to interact with it, but I can't seem to get my head round how to do it (if you even can) I've been trying things like -

    var reportController = Traccar.app.getController("Traccar.view.ReportController");
    reportController.test();

But, I get an error like this

```    Uncaught TypeError: controller.doInit is not a function
```    at constructor.getController (ext-all-debug.js:95199:28)
```    at constructor.onQuickReportClick (DevicesController.js:109:38)
```    at Object.callback (ext-all-debug.js:8705:32)
```    at constructor.fireHandler (ext-all-debug.js:144259:17)
```    at constructor.onClick (ext-all-debug.js:144241:16)
```    at constructor.fire (ext-all-debug.js:20731:42)
```    at constructor.fire (ext-all-debug.js:34336:27)
```    at constructor.publish (ext-all-debug.js:34296:28)
```    at constructor.publishDelegatedDomEvent (ext-all-debug.js:34318:14)
```    at constructor.doDelegatedEvent (ext-all-debug.js:34361:16)

The test method is very simple at the moment, just to prove I'm getting there -

test: function () {
    showToast("test - succsfully in report controller", "test");
},

Any pointers / guidance / advice would be greatly appreciated

2

There are 2 best solutions below

1
On

Advice

It is a NoGo to call a controller from another controller.

The controller is a viewController, created when the view is created to react to userinput from that view. Worstcase: the other view does not exist and therefore the viewController has not been created.


If you really have to

You want to follow Peters comment and run:

Ext.first('reportView').getController()
// or faster and prefered
// add an id to the view => reportViewId
Ext.getCmp('reportViewId').getController()

Way better

Make use of Events or setup your own Eventbus

Setup EventBus

after your app started call

Traccar.Bus = new Ext.util.Observable();

With that in place you can fire an event in one viewController:

/**
 * @param {string} eventName
 * @param {object} args
 */
Traccar.Bus.fireEvent(eventName, args);

In the receiving viewController you previously set a listener

onOtherViewControllerFire: function(args) {...}
init: function() {
    Traccar.Bus.on(eventName, this.onOtherViewControllerFire);
}
1
On

You can use events. You don't actually need to set up a Bus for it. You can just call something like this:

this.fireEvent('selectevent', position);

And the subscribe in another place like this:

    config: {
        listen: {
            controller: {
                '*': {
                    selectdevice: 'deselectEvent',
                    selectreport: 'deselectEvent'
                },

Events are actually used a lot in the Traccar app. You can just search existing usages.