简体   繁体   中英

Using angular-ui-bootstrap for popup

I'm very much naive in angular and typescript. I'm trying to create a popup on clicking a image. I found a SO link which answers this question using IMODALSERVICE.

How to use angular-ui-bootstrap (modals) in typescript?

However for some reason ng.ui.bootstrap.IModalService type is not recognized in project. Am I doing anything wrong or the SO post has some mistakes. I did add all the angular dependencies in my project.

For your programming environment (IDE like Visual Studio) to be able to recognize types you need to add typescript definitions.

The best way to get the angular-bootstrap-ui is using the TSD tool

Then with the command line at your project you could run the command: tsd install angular-ui-bootstrap --resolve --save

and essentially that would "install" the file angular-ui-bootstrap.d.ts in your typings folder. If your development environment does not detect it simply add /// <reference path="../../../typings/angular-ui-bootstrap/angular-ui-bootstrap.d.ts" /> at the top of your typescript file. Notice that the path must match depending on your folder structures (that's only an example).

After that I personally like to wrap the angular-ui-bootstrap modal in a service, so I'd create a template confirmation-modal.html as follows:

<div>
    <div class="modal-header">
        <h3 class="modal-title">{{ modal.title }}</h3>
    </div>
    <div class="modal-body">
        {{ modal.bodyText }}
    </div>
    <div class="modal-footer">
        <button class="btn btn-primary" type="button" ng-click="modal.ok()">OK</button>
        <button class="btn btn-default" type="button" ng-click="modal.cancel()">Cancel</button>
    </div>
</div>

That's the view for the modal. It's a basic confirmation dialog with buttons OK and Cancel, a title and a body text. You can get the idea though.

Then I'd create a service modal.service.ts with a function to show a confirmation dialog that accepts a title, a bodyText and a callback function for the OK button and optionally for the CANCEL button. For example:

/// <reference path="../../../typings/angular-ui-bootstrap/angular-ui-bootstrap.d.ts" />
module app.services {
    "use strict";

    interface IModalParams {
        title: string;
        bodyText: string;
        onOk(): void;
        onCancel(): void;
    }

    interface IModalConfirmationInstance {
        title: string;
        bodyText: string;
        ok(): void;
        cancel(): void;
    }

    export interface IModalService {
        showConfirmDialog(title: string, bodyText: string, onOk: () => void, onCancel?: () => void): void;
    }

    class ModalInstanceController implements IModalConfirmationInstance {

        public static $inject = [
            "$uibModalInstance",
            "modalParams"
        ];

        constructor(
            private $uibModalInstance: angular.ui.bootstrap.IModalServiceInstance,
            private modalParams: IModalParams) {
        }

        public title: string = this.modalParams.title;

        public bodyText: string = this.modalParams.bodyText;

        public ok(): void {
            this.modalParams.onOk();
            this.$uibModalInstance.close();
        }

        public cancel(): void {
            if (this.modalParams.onCancel) {
                this.modalParams.onCancel();
            }
            this.$uibModalInstance.dismiss();
        }
    }

    class ModalService implements IModalService {
        constructor(
            private $uibModal: angular.ui.bootstrap.IModalService) {
        }

        public showConfirmDialog(title: string, bodyText: string, onOk: () => void, onCancel?: () => void): void {
            console.log("show modal");

            let modalParams: IModalParams = {
                title: title,
                bodyText: bodyText,
                onOk: onOk,
                onCancel: onCancel 
            };

            let modalInstance = this.$uibModal.open({
                animation: true,
                templateUrl: "/app/confirmation-modal.html",
                controller: ModalInstanceController,
                controllerAs: "modal",
                size: null, // default size
                resolve: {
                    modalParams: () => modalParams
                }
            });
        }
    }

    factory.$inject = [
        "$uibModal"
    ];

    function factory(
        $uibModal: angular.ui.bootstrap.IModalService): IModalService {
        return new ModalService($uibModal);
    }

    angular
        .module("app.services")
        .factory("app.services.ModalService", factory);
}

Notice that in addition to the service, in the same file I have created a controller to handle the modal instance and that the resolve property is passing an object to that controller with all the necessary parameters wrapped in it. Also notice that I don't like using $scope and I prefer using the controller as approach. That's why I have the controller property as controllerAs defined as "modal" so that in the template modal view I can refer to the controller with the word modal (or whatever you choose).

Now all my functionality is wrapped in a service, so I can show my confirmation dialog modal from anywhere where my service has been injected. For example, let's say I have a view attached to a controller somewhere..

<div ng-controller="app.foo.MyController as myCtrl">
  <!-- some things and below a button to delete something with confirmation (or whatever) -->
  <button ng-click="myCtrl.delete()">
     <span class="fa fa-trash-o" aria-hidden="true"></span>
  </button>
</div>

Then in that MyController I could have for example the function that gets triggered when clicking on the delete button:

module app.foo {
    "use strict";

    interface IMyControllerScope {
        delete(): void;
    }

    class MyController  implements IMyControllerScope {
        public static $inject = ["app.services.ModalService"];

        constructor(private modalService: app.services.IModalService) {
        }

        public delete(): void {
            this.modalService.showConfirmDialog("Delete Things", "Are you sure?",
                () => {
                    console.log("The button OK has been click. Do things");
                    // some actions to execute when the button OK has been pressed
                });
        }
    }

    angular
        .module("app.foo")
        .controller("app.foo.MyController ", MyController );
}

Notice how I inject the service that wraps the modal functionality and the only thing I have to do is provide a title and body for the modal and the action to execute when OK (and optionally Cancel) is clicked.

Make sure you've installed angular-ui-bootstrap.d.ts https://www.nuget.org/packages/angular-ui-bootstrap.TypeScript.DefinitelyTyped/

if you're using visual studio usually package get install in Scripts/typings/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM