12

I'd like to edit some data from a table using a modal. There are various interfaces in the typescript definitions for angular-ui-bootstrap from definitelyTyped, however they are undocumented and I'm not able to find any examples on how to use them.

  • IModalScope
  • IModalService
  • IModalServiceInstance
  • IModalSettings
  • IModalStackService

https://github.com/borisyankov/DefinitelyTyped/blob/master/angular-ui-bootstrap/angular-ui-bootstrap.d.ts#L146

What I'd like to achieve is something like this:

layout

Am I right to assume that both ItemsListController and ItemDetailModalController need an instance of the same scope in order to exchange the data? And how can I define the controller and the template for the modal directive using the interfaces above?

I already found this non-typescript example here: https://angular-ui.github.io/bootstrap/#/modal

However, as a beginner I've got a hard time understanding what's going on if samples throw everything in one single file without separating the concerns.

2 Answers 2

22

The instance injected by angular will be of type ng.ui.bootstrap.IModalService.

And since you are using "controller as" syntax, there is no need to start using $scope here, instead you can use resolve as shown in the angular-ui modal example.

Here's the example code:

class ItemsListController {
    static controllerId = 'ItemsListController';
    static $inject = ['$modal'];

    data = [
        { value1: 'Item1Value1', value2: 'Item1Value2' },
        { value1: 'Item2Value1', value2: 'Item2Value2' }
    ];

    constructor(private $modal: ng.ui.bootstrap.IModalService) { }

    edit(item) {
        var options: ng.ui.bootstrap.IModalSettings = {
            templateUrl: 'modal.html',
            controller: ItemDetailController.controllerId + ' as modal',
            resolve: {
                item: () => item // <- this will pass the same instance 
                                 // of the item displayed in the table to the modal
            }
        };

        this.$modal.open(options).result
            .then(updatedItem => this.save(updatedItem));
            //.then(_ => this.save(item)); // <- this works the same way as the line above
    }

    save(item) {
        console.log('saving', item);
    }
}

class ItemDetailController {
    static controllerId = 'ItemDetailController';
    static $inject = ['$modalInstance', 'item'];

    constructor(private $modalInstance: ng.ui.bootstrap.IModalServiceInstance, public item) { }

    save() {
        this.$modalInstance.close(this.item); // passing this item back 
                                              // is not necessary since it 
                                              // is the same instance of the 
                                              // item sent to the modal
    }

    cancel() {
        this.$modalInstance.dismiss('cancel');
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Hi Juanjo, I like this style that you are using and I prefer it. However, I have some problems. I have posted my question in a separate post in here: stackoverflow.com/questions/34103868/…
1

Am I right to assume that both ItemsListController and ItemDetailModalController need an instance of the same scope in order to exchange the data?

Yes. I actually think of modals as an extension of ItemsListController containing members shownDetails:ItemDetailModalController. Which means you don't need to come up with a messy way of sharing $scope as its just a single $scope.

And how can I define the controller and the template for the modal directive using the interfaces above?

This is what I have (note that you are sharing the scope):

            this.$modal.open({
                templateUrl: 'path/To/ItemModalDetails.html',
                scope: this.$scope,
            })

Where $modal:IModalService corresponds to what angular strap gives you : http://angular-ui.github.io/bootstrap/#/modal

4 Comments

So does the controller actually configures/calls the modal? Isn't this breaking SOC?
No. Its the same as doing error = "bad thing happened" from the controller. Controller drives the UI, just doesn't use $element
Yes, I was really confused the first time I saw $element, though it seems very common in examples. I just thought there was a way to configure the modal on the HTML side. Well, guess everythings clear now (except for the DT interfaces)
I am using a really old version (1.5 years old). The interfaces correspond to the new version of angular strap and I've updated the answer to reflect that. AKA The DT interfaces are correct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.