Access data from webContents.send(..) in Angular C

2019-07-27 06:46发布

问题:

I am pretty new to Electron and am currently building a small application that reuses some code from an Angular application that I built some time ago.

Here is what I am trying to do: I have one main BrowserWindow (that is being filled with data from a webservice which I access using angular), when the user clicks one of the buttons I want to open another BrowserWindow and display some data in it (the data is related to what the user clicked). I figured out how to open another BrowserWindow just fine and also how to pass some arguments to it, see code sample below.

This code is being executed when the user clicks the button, a new BrowserWindow opens.

const BrowserWindow = remote.BrowserWindow;
var cubeWindow = new BrowserWindow({ width: 800, height: 600, frame: false });
var cube = path.resolve(__dirname, '../cube.html');
cubeWindow.loadURL(cube);

var data = {
  id: "1",
  name: "this"
};

cubeWindow.webContents.on('did-finish-load', ()=> {
  cubeWindow.webContents.send('cube-data', data);
})

Here I access the data in the freshly opened BrowserWindow (this javascript file is referenced in cube.html):

require('electron').ipcRenderer.on('cube-data', (event, message) => {
    console.log(message);
});

The content of the data object is being logged in the new BrowserWindow, so far so good. Now to my question: How do I get access to the data object in an Angular app/controller that is running in cube.html?

I tried to do it like this, but that doesn't work:

var data;

require('electron').ipcRenderer.on('cube-data', (event, message) => {
    console.log(message);
    data = message;
});

angular.module('testApp', [])
    .controller('appCtrl', function($scope) {
        $scope.data = data;
        console.log('Data: ' + $scope.data);
    });

The log entry from the Angular controller says data is undefined, I assume that is because the controller is actually evaluated before the message is sent/received by the ipcRenderer?

Is there a way to access the sent message in Angular?

回答1:

Try putting the cube-data event handler inside the controller code:

angular.module('testApp', [])
    .controller('appCtrl', function($scope) {
        $scope.model = {
            data: null
        }

        function attachCubeDataHandler() {
            require('electron').ipcRenderer.on('cube-data', (event, message) => {
                console.log(message);
                $scope.model.data = message;
            });
        }

        function initialize() {
            attachCubeDataHandler();
        }

        // Invoke initialization
        initialize();
    });

This way you firstly initialize the controller and then parse the event response when it comes. Moreover, if you put the code inside controller, you can directly use $scope to update the view's data. I wrapped data with another object (model) to ensure that view updates when data object changes.



回答2:

Ok I figured it out: Based on this post by jdfwarrior on atom.io we have to use a little Angular $timeout hack to make things work. After I changed the code snippet provided by PJDev to the following, it worked. It now logs the content of the message and also displays it in the view (cube.html).

angular.module('testApp', [])
    .controller('appCtrl', ['$timeout', '$scope', function($timeout, $scope) {
        $scope.model = {
            data: null
        }

        function attachCubeDataHandler() {
            require('electron').ipcRenderer.on('cube-data', (event, message) => {
                $timeout(function() {
                    $scope.model.data = message;
                    console.log("in timeout: " + message);
                },0);
            });
        }

        function initialize() {
            attachCubeDataHandler();
        }

        // Invoke initialization
        initialize();
    });