AngularJS - 移动 Material mdDialog 服务

AngularJS - moving Material mdDialog to service

我正在尝试清理我的其中一个变得太大的控制器的代码。首先,我决定将使用 AngularJS Material mdDialog 的与会者注册移动到服务中。

原始(和工作)控制器代码如下所示:

myApp.controller('RegistrationController', ['$scope','$routeParams','$rootScope','$location','$filter','$mdDialog', function($scope, $routeParams, $rootScope, $location, $filter, $mdDialog){

    var attendee = this;
    attendees = [];
...

    $scope.addAttendee = function(ev) {
        $mdDialog.show({
        controller: DialogController,
        templateUrl: 'views/regForm.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: ev,
        clickOutsideToClose:true,
        controllerAs: 'attendee',
        fullscreen: $scope.customFullscreen, // Only for -xs, -sm breakpoints.
        locals: {parent: $scope}
    })
    .then(function(response){
        attendees.push(response);

        console.log(attendees);
        console.log(attendees.length);
    })
  };

    function DialogController($scope, $mdDialog) {

        var attendee = this;

        $scope.hide = function() {
            $mdDialog.hide();
        };

        $scope.cancel = function() {
            $mdDialog.cancel();
        };

        $scope.save = function(response) {
            $mdDialog.hide(response);
        };
    }

}]);

和控制器分离后的代码:

myApp.controller('RegistrationController', ['$scope','$routeParams','$rootScope','$location','$filter','$mdDialog','Attendees', function($scope, $routeParams, $rootScope, $location, $filter, $mdDialog, Attendees){

...


    $scope.attendees= Attendees.list();

    $scope.addAttendee = function (ev) {
        Attendees.add(ev);
    }

    $scope.deleteAttendee = function (id) {
        Attendees.delete(id);
    }

}]);

新服务代码如下:

myApp.service('Attendees', ['$mdDialog', function ($mdDialog) {
    //to create unique attendee id
    var uid = 1;

    //attendees array to hold list of all attendees
    var attendees = [{
        id: 0,
        firstName: "",
        lastName: "",
        email: "",
        phone: ""
    }];

    //add method create a new attendee
    this.add = function(ev) {
        $mdDialog.show({
        controller: DialogController,
        templateUrl: 'views/regForm.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: ev,
        clickOutsideToClose:true,
        controllerAs: 'attendee',
        fullscreen: this.customFullscreen, // Only for -xs, -sm breakpoints.
        //locals: {parent: $scope}
    })
    .then(function(response){
        attendees.push(response);

        console.log(attendees);
        console.log(attendees.length);
    })
  };

    //simply search attendees list for given id
    //and returns the attendee object if found
    this.get = function (id) {
        for (i in attendees) {
            if (attendees[i].id == id) {
                return attendees[i];
            }
        }

    }

    //iterate through attendees list and delete 
    //attendee if found
    this.delete = function (id) {
        for (i in attendees) {
            if (attendees[i].id == id) {
                attendees.splice(i, 1);
            }
        }
    }

    //simply returns the attendees list
    this.list = function () {
        return attendees;
    }

    function DialogController($mdDialog) {

        this.hide = function() {
            $mdDialog.hide();
        };

        this.cancel = function() {
            $mdDialog.cancel();
        };

        this.save = function(response) {
            $mdDialog.hide(response);
        };
    }

}]);

但我无法从使用 ng-click=save(attendee) 的生成的 mdDialog 框 "save" 关闭对话框。

我做错了什么?

$scope 无法在服务创建时注入到服务中。您需要重构服务及其方法,这样您就不会将 $scope 注入其中,而是在调用它们时将当前范围传递给服务方法。

我实际上有一个我注入的通知模块,它使用 $mdDialog。下面是它的代码。或许会有帮助。

(() => {
    "use strict";
    class notification {
        constructor($mdToast, $mdDialog, $state) {
            /* @ngInject */
            this.toast = $mdToast
            this.dialog = $mdDialog
            this.state = $state

            /* properties */
            this.transitioning = false
            this.working = false
        }
        openHelp() {
            this.showAlert({
                "title": "Help",
                "textContent": `Help is on the way for ${this.state.current.name}!`,
                "ok": "OK"
            })
        }
        showAlert(options) {
            if (angular.isString(options)) {
                var text = angular.copy(options)
                options = {}
                options.textContent = text
                options.title = " "
            }
            if (!options.ok) {
                options.ok = "OK"
            }
            if (!options.clickOutsideToClose) {
                options.clickOutsideToClose = true
            }
            if (!options.ariaLabel) {
                options.ariaLabel = 'Alert'
            }
            if (!options.title) {
                options.title = "Alert"
            }
            return this.dialog.show(this.dialog.alert(options))
        }
        showConfirm(options) {
            if (angular.isString(options)) {
                var text = angular.copy(options)
                options = {}
                options.textContent = text
                options.title = " "
            }
            if (!options.ok) {
                options.ok = "OK"
            }
            if (!options.cancel) {
                options.cancel = "Cancel"
            }
            if (!options.clickOutsideToClose) {
                options.clickOutsideToClose = false
            }
            if (!options.ariaLabel) {
                options.ariaLabel = 'Confirm'
            }
            if (!options.title) {
                options.title = "Confirm"
            }
            return this.dialog.show(this.dialog.confirm(options))
        }
        showToast(toastMessage, position) {
            if (!position) { position = 'top' }
            return this.toast.show(this.toast.simple()
                .content(toastMessage)
                .position(position)
                .action('OK'))
        }
        showYesNo(options) {
            options.ok = "Yes"
            options.cancel = "No"
            return this.showConfirm(options)
        }
        uc() {
            return this.showAlert({
                htmlContent: "<img src='img\underconstruction.jpg'>",
                ok: "OK",
                title: "Under Construction"
            })
        }

    }
    notification.$inject = ['$mdToast', '$mdDialog', '$state']
    angular.module('NOTIFICATION', []).factory("notification", notification)
})()

然后将通知(小写)注入我的控制器以便使用它。我将通知存储在控制器的 属性 中,然后用这样的方式调用它:

this.notification.showYesNo({
                    clickOutsideToClose: true,
                    title: 'Delete Customer Setup?',
                    htmlContent: `Are you sure you want to Permanently Delete the Customer Setup for ${custLabel}?`,
                    ariaLabel: 'Delete Dialog'
                }).then(() => { ...
                    this.notification.working = true
                    this.ezo.EDI_CUSTOMER.remove(this.currentId).then(() => {
                        this.primaryTab = 0
                        this.removeCustomerFromList(this.currentId)
                        this.currentId = 0
                        this.notification.working = false
                    }, error => {
                        this.notification.working = false
                        this.notification.showAlert({
                            title: "Error",
                            htmlContent: error
                        })

                    })

I'm not able to "save" from the spawned mdDialog box which uses ng-click=save(attendee) neither close the dialog box.

使用 "controllerAs" 语法实例化控制器时,使用实例化时使用的名称:

<button ng-click="ctrl.save(ctrl.attendee)">Save</button>
this.add = function(ev) {
    $mdDialog.show({
    controller: DialogController,
    templateUrl: 'views/regForm.tmpl.html',
    parent: angular.element(document.body),
    targetEvent: ev,
    clickOutsideToClose:true,
    controllerAs:  ̶'̶a̶t̶t̶e̶n̶d̶e̶e̶'̶ 'ctrl',
    fullscreen: this.customFullscreen, // Only for -xs, -sm breakpoints.
    //locals: {parent: $scope}
})
.then(function(response){
    attendees.push(response);

    console.log(attendees);
    console.log(attendees.length);
    return response;     
});

为避免混淆,请选择与数据名称不同的控制器实例名称。