Returning scope items to parent scope with $mdDialog.show()

14,782

Solution 1

You can pass the $scope of your controller to your $mdDialog as an example below

$mdDialog.show({
    parent: angular.element(document.body),
    template: tmpl,
    scope: $scope,
    controller: 'myCtrl'
});

Check plunkr : http://plnkr.co/edit/0hFWEyWdetTXcPLPkbmQ?p=preview

To move application logic to factory you will be doing something like this

$scope.upload = factory.upload(files,$scope.username); 

and factory will have method

 factory.upload = function(files,username)
 {
  function (files) {
    if (files && files.length) {
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            Upload.upload({
                url: 'upload/url',
                fields: {'username': username},
                file: file
            }).progress(function (evt) {
                var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
            }).success(function (data, status, headers, config) {
                console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
            });
        }
    }
};

Solution 2

setting scope: $scope in $mdDialog.show() will carry the scope into the modal, and preserveScope: true should keep the newly added elements to the $scope, otherwise it will remove them afterward?

$mdDialog.show({
  template: tmpl,
  scope: $scope,
  preserveScope: true,
  controller: 'myCtrl'
});
Share:
14,782
nikk wong
Author by

nikk wong

projects can be found at nikkwong.com. most notable thing I've done is found Fractals. Interested in programming, the human brain, and the universe.

Updated on June 16, 2022

Comments

  • nikk wong
    nikk wong almost 2 years

    Yo! I have a controller which houses a bunch of items on its $scope. One of the scope items, $scope.openDialog opens a $mdDialog via $mdDialog.show(). The object passed into $mdDialog.show has a template which houses controls for uploading files via the ng-file-upload project, which you can read about here.

    I would like it if the items uploaded in the dialog window would be available in the main controller after exiting out of the dialog window. I am not sure as to whether the controller for the dialog window should reference the main myCtrl controller or use its own, and how to take make uploaded files available to myCtrl.

    Here is the angular code:

    angular.module('app', ['ngMaterial', 'ngFileUpload'])
    .controller('myCtrl', ['$scope', '$mdDialog', 'Upload', function($scope, $mdDialog, Upload) {
      var tmpl = "<md-dialog>\n" +
        "<md-dialog-content>\n" +
        "    <input type=\"text\" ng-model=\"username\"></br></br>\n" +
        "    <input type=\"checkbox\" ng-model=\"multiple\">upload multiple file</br></br>\n" +
        "    watching model:\n" +
        "    <div class=\"button\" ngf-select ng-model=\"files\" ngf-multiple=\"multiple\">Select File</div>\n" +
        "    on file change:\n" +
        "    <div class=\"button\" ngf-select ngf-change=\"upload($files)\" ngf-multiple=\"multiple\">Select File</div>\n" +
        "    Drop File:\n" +
        "    <div ngf-drop ngf-select ng-model=\"files\" class=\"drop-box\" \n" +
        "        ngf-drag-over-class=\"dragover\" ngf-multiple=\"true\" ngf-allow-dir=\"true\"\n" +
        "        accept=\"image/*,application/pdf\">Drop pdfs or images here or click to upload</div>\n" +
        "    <div ngf-no-file-drop>File Drag/Drop is not supported for this browser</div>\n" +
        "    Image thumbnail: <img ngf-src=\"files[0]\">\n" +
        "    Files:\n" +
        "    <ul>\n" +
        "        <li ng-repeat=\"f in files\" style=\"font:smaller\">{{f.name}}</li>\n" +
        "    </ul>\n" +
        "    Upload Log:\n" +
        "    <pre>{{log}}</pre>\n" +
        "<md-action><div class=\"button\" ng-click=\"close()\">close!</div></md-action>\n" +
        "<md-action><div class=\"button\" ng-click=\"upload()\">upload!</div></md-action>\n" +
        "</md-dialog-content>\n" +
        "</md-dialog>";
    $scope.files = ['files should appear here', 'files 1', 'file2'];
    $scope.openDialog = function () {
      $mdDialog.show({
            parent: angular.element(document.body),
            template: tmpl,
            controller: 'myCtrl'
        });
    };
    $scope.close = function() {
      $mdDialog.hide();
    };
    $scope.$watch('files', function () {
        $scope.upload($scope.files);
    });
    $scope.upload = function (files) {
            if (files && files.length) {
                for (var i = 0; i < files.length; i++) {
                    var file = files[i];
                    Upload.upload({
                        url: 'upload/url',
                        fields: {'username': $scope.username},
                        file: file
                    }).progress(function (evt) {
                        var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                        console.log('progress: ' + progressPercentage + '% ' + evt.config.file.name);
                    }).success(function (data, status, headers, config) {
                        console.log('file ' + config.file.name + 'uploaded. Response: ' + data);
                    });
                }
            }
        };
    }]); 
    

    BTW: As a housekeeping note, I often hear that application logic shouldn't be passed into a controller. In this situation, how would you move $scope.upload into a factory, given that it references $scope and $scope is not available in factories?

    Thanks for the help.

    Plnkr: http://plnkr.co/edit/e2MYdEABhj34ahtPTO0g?p=preview