Javascript 如何在 angular 1.5 中使用带有 ui.bootstrap.modal 的 angular 组件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36401375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:00:42  来源:igfitidea点击:

How to use angular component with ui.bootstrap.modal in angular 1.5?

javascriptangularjsangular-ui-bootstrap

提问by wtadahiro

I'd like to use angular component with ui.bootstrap.modal. angular version is 1.5.
I tried to use like below.

我想在 ui.bootstrap.modal 中使用角度组件。角度版本是 1.5。
我尝试使用如下。

component

成分

function MyComponentController($uibModalInstance){
  var ctrl = this;

  ctrl.doSomething = function() {
    //doSomething
  }
}

app.component('myComponent', {
  contoller: MyComponentController,
  templateUrl: '/path/to/myComponent.html'
}

parent controller

父控制器

function parentController($uibModal){
  var ctrl = this;

  ctrl.openModal = function(){
    var modalInstance = $uibModal.open({
      template: '<my-component></my-component>'

  }
}

And when I execute parentController.openModal(), I got the error of $injector:unpr Unknown Provideralthough modal window is open.
Is there a way to use angular component with ui.bootstrap.modal? If you need more information, please let me know that.
Thank you.

当我执行时parentController.openModal(),尽管模式窗口已打开,但我收到了$injector:unpr Unknown Provider的错误。
有没有办法在 ui.bootstrap.modal 中使用角度组件?如果您需要更多信息,请告诉我。
谢谢你。

EDIT
I've got a way to use component with ui.bootstrap.modal from Renato Machado, Thanks Renato.
But I feel It's a little bit complicated and not convenient. So finally I think that it's better to use component inside the modal.
Modal is opened with regular way(just set controller and template in $uibModal.open({})) and the modal contains the component which has logics you want to use commonly.
Modal should have only simple logics that are related with modal like close modal window.
Another logics mainly related with business/Application should be in component.
It makes easy to commonalize.

编辑
我有一种方法可以使用来自 Renato Machado 的 ui.bootstrap.modal 组件,感谢 Renato。
但是我觉得有点复杂,不方便。所以最后我认为最好在模态内使用组件。
模态以常规方式打开(只需在 中设置控制器和模板$uibModal.open({})),模态包含具有您想要常用的逻辑的组件。
模态应该只有与模态相关的简单逻辑,如关闭模态窗口。
另一个主要与业务/应用相关的逻辑应该在组件中。
它使通用化变得容易。

回答by PCalouche

EDIT: As of UI Bootstrap 2.1.0 there is native support for component in bootstrap modals. It looks like there have been several quick releases after 2.1.0 to fix some issues with the modals, so I'd be sure to grab the latest.

编辑:从 UI Bootstrap 2.1.0 开始,对引导模式中的组件提供本机支持。看起来在 2.1.0 之后有几个快速版本来修复模态的一些问题,所以我一定要抓住最新的。

See this Plunk for a version using UI Bootstrap 2.1.0+

有关使用 UI Bootstrap 2.1.0+ 的版本,请参阅此 Plunk

http://plnkr.co/edit/jy8WHfJLnMMldMQRj1tf?p=preview

http://plnkr.co/edit/jy8WHfJLnMMldMQRj1tf?p=preview

angular.module('app', ['ngAnimate', 'ui.bootstrap']);

angular.module('app')
  .component('myContent', {
     template: 'I am content! <button type="button" class="btn btn-default" ng-click="$ctrl.open()">Open Modal</button>',
     controller: function($uibModal) {
        $ctrl = this;
        $ctrl.dataForModal = {
        name: 'NameToEdit',
        value: 'ValueToEdit'
     }

    $ctrl.open = function() {
      $uibModal.open({
         component: "myModal",
         resolve: {
           modalData: function() {
             return $ctrl.dataForModal;
           }
         }
       }).result.then(function(result) {
            console.info("I was closed, so do what I need to do myContent's  controller now.  Result was->");
      console.info(result);
       }, function(reason) {
           console.info("I was dimissed, so do what I need to do myContent's controller now.  Reason was->" + reason);
       });
    };
  }
});

angular.module('app')
  .component('myModal', {
template: `<div class="modal-body"><div>{{$ctrl.greeting}}</div> 
<label>Name To Edit</label> <input ng-model="$ctrl.modalData.name"><br>
<label>Value To Edit</label> <input ng-model="$ctrl.modalData.value"><br>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleClose()">Close Modal</button>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleDismiss()">Dimiss Modal</button>
</div>`,
  bindings: {
    modalInstance: "<",
    resolve: "<"
  },
  controller: [function() {
    var $ctrl = this;
    $ctrl.$onInit = function() {
      $ctrl.modalData = $ctrl.resolve.modalData;
    }
    $ctrl.handleClose = function() {
      console.info("in handle close");
      $ctrl.modalInstance.close($ctrl.modalData);
    };
    $ctrl.handleDismiss = function() {
      console.info("in handle dismiss");
      $ctrl.modalInstance.dismiss("cancel");
    };
  }]
});

Original answer is below:

原答案如下:

I was trying to figure this out the other day too. I took the information I found in this post along with this link to try and come up with an alternate way to accomplish this. These are some reference links I found that helped me:

前几天我也试图弄清楚这一点。我利用我在这篇文章中找到的信息以及这个链接来尝试想出另一种方法来实现这一点。这些是我发现对我有帮助的一些参考链接:

https://github.com/angular-ui/bootstrap/issues/5683

https://github.com/angular-ui/bootstrap/issues/5683

http://www.codelord.net/(this one helped in understanding passing arguments to callbacks in components)

http://www.codelord.net/(这有助于理解向组件中的回调传递参数)

Also here is a Plunk: http://plnkr.co/edit/PjQdBUq0akXP2fn5sYZs?p=preview

这里还有一个 Plunk:http://plnkr.co/edit/PjQdBUq0akXP2fn5sYZs?p=preview

I tried to demonstrate a common real world scenario of using a modal to edit some data.

我试图演示使用模态编辑一些数据的常见现实世界场景。

angular.module('app', ['ngAnimate', 'ui.bootstrap']);

angular.module('app')
.component('myContent', {
    template: 'I am content! <button type="button" class="btn btn-default" ng-click="$ctrl.open()">Open Modal</button>',
    controller: function($uibModal) {
        $ctrl = this;
        $ctrl.dataForModal = {
            name: 'NameToEdit',
            value: 'ValueToEdit'
        }
        $ctrl.open = function() {
            $uibModal.open({
                template: '<my-modal greeting="$ctrl.greeting" modal-data="$ctrl.modalData" $close="$close(result)" $dismiss="$dismiss(reason)"></my-modal>',
                controller: ['modalData', function(modalData) {
                    var $ctrl = this;
                    $ctrl.greeting = 'I am a modal!'
                    $ctrl.modalData = modalData;
                }],
                controllerAs: '$ctrl',
                resolve: {
                    modalData: $ctrl.dataForModal
                }
            }).result.then(function(result) {
                console.info("I was closed, so do what I need to do myContent's controller now and result was->");
                console.info(result);
            }, function(reason) {
                console.info("I was dimissed, so do what I need to do myContent's controller now and reason was->" + reason);
            });
        };
    }
});

angular.module('app')
.component('myModal', {
    template: `<div class="modal-body"><div>{{$ctrl.greeting}}</div> 
<label>Name To Edit</label> <input ng-model="$ctrl.modalData.name"><br>
<label>Value To Edit</label> <input ng-model="$ctrl.modalData.value"><br>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleClose()">Close Modal</button>
<button class="btn btn-warning" type="button" ng-click="$ctrl.handleDismiss()">Dimiss Modal</button>
</div>`,
    bindings: {
        $close: '&',
        $dismiss: '&',
        greeting: '<',
        modalData: '<'
    },
    controller: [function() {
        var $ctrl = this;
        $ctrl.handleClose = function() {
            console.info("in handle close");
            $ctrl.$close({
                result: $ctrl.modalData
            });
        };
        $ctrl.handleDismiss = function() {
            console.info("in handle dismiss");
            $ctrl.$dismiss({
                reason: 'cancel'
            });
        };
    }],
});

回答by kevinius

There is no need to make it more complicated by passing along the parent controller, you can just access it from within the .component that displays the modal.

没有必要通过传递父控制器来让它变得更复杂,你可以从显示模态的 .component 中访问它。

Component

成分

/**
 * @ngdoc component
 * @name fsad.component:video
 *
 * @description <fsad-video> component, in development...
 *
 */


(function () {
  'use strict';

  angular.module('fsad').component('fsadVideo', {
    bindings: {},
    templateUrl: function(appConstant){return appConstant.paths.modules.fsad + 'leefloon/fsad-video.html'},
    controller: controller
  });

  controller.$inject = ['$scope'];
  function controller($scope){

    var $ctrl = this;

    setDataModel();

    /****************************************************************/

    $ctrl.ui.close = close;

    /****************************************************************/

    function setDataModel(){

      $ctrl.ui = {};

    }
    function close(){
      $scope.$parent.$close();
    }

  }

}());

Opening the modal

打开模态

  var modalInstance = $uibModal.open({
    backdrop: 'static',
    keyboard: true,
    backdropClick: false,
    template: '<fsad-video></fsad-video>',
    windowClass: 'edit-contactenblad',
  });

Since you are stating that the template is a component, the $scope.$parent will always be pointing to the modal instance. Allowing you to access the $close() function.

由于您声明模板是一个组件,因此 $scope.$parent 将始终指向模态实例。允许您访问 $close() 函数。

Passing and receiving data

传递和接收数据

If you need to pass data to the component, or receive data back from the component, you can do it like this.

如果你需要向组件传递数据,或者从组件接收数据,你可以这样做。

  var modalInstance = $uibModal.open({
    backdrop: 'static',
    keyboard: true,
    backdropClick: false,
    template: '<fsad-video method="$ctrl.method" on-viewed="$ctrl.userHasViewedVideo(time)"></fsad-ideo>',
    controller: function(){
      this.method = method;
      this.userHasViewedVideo = function(time){}
    },
    controllerAs: '$ctrl',
    windowClass: 'edit-medewerker',
  });

Just on a side note, i'm using this structure style guideto create the component.

顺便提一下,我正在使用此结构样式指南来创建组件。

回答by Matt Janssen

If you want access to the $uibModal's $close()and $dismiss()functions, along with some parent data and function binding within your component, you can pass them all along as such:

如果您想访问 $uibModal$close()$dismiss()函数,以及组件中的一些父数据和函数绑定,您可以将它们全部传递如下:

Open Modal Logic

开放模态逻辑

$uibModal.open({
    template: '<login close="$close()" dismiss="$dismiss()" ' +
        'email="$ctrl.cookieEmail" check-login="$ctrl.ajaxLogin(user, pass)"></login>',
    controller: function () {
        this.cookieEmail = $cookies.get('savedEmail');
        this.ajaxLogin = AjaxLoginService.login;
    },
    controllerAs: '$ctrl'
});

Modal Login Component

模态登录组件

{
    templateUrl: 'view/login.html',
    bindings: {
        email: '<',
        checkLogin: '&',
        close: '&',
        dismiss: '&'
    },
    controller: function () {
        var viewModel = this;

        viewModel.password = '';

        viewModel.submit = function () {
            viewModel.checkLogin(
                { user: viewModel.email, pass: viewModel.password }
            ).then(function (success) {
                viewModel.close();
            });
        }
    }
}

Modal HTML

模态 HTML

<form ng-submit="$ctrl.submit()">
    <input type="text" ng-model="$ctrl.email" />
    <input type="password" ng-model="$ctrl.password" />
    <button type="button" ng-click="$ctrl.dismiss()">Cancel</button>
    <button type="submit">Login</button>
</form>

The AngularJS 1.5 docs are a little sparse, but they show the usage of the &binding as a function wrapper: https://docs.angularjs.org/guide/component

AngularJS 1.5 文档有点稀疏,但它们显示了&绑定作为函数包装器的用法:https: //docs.angularjs.org/guide/component

回答by Renato Machado

You need to pass the parent controller to the modal component with the modal instance on it. To do that you need to append the generate HTML of the modal in the parent component

您需要将父控制器传递给带有模态实例的模态组件。为此,您需要在父组件中附加模态的生成 HTML

parent component

父组件

$ctrl.openModal = function(){
    $ctrl.modalInstance = $uibModal.open({
        template: '<your-modal></your-modal>',
        appendTo : $document.find('parentComponent')
    });
}

modal component

模态组件

.component('yourModal', {
        templateUrl: 'path/to/modal.html',
        replace: true,
        require: {
            parent : '^parentComponent'
        },
        controller: ModalCtrl
    });

function ModalCtrl() {
    var $ctrl = this;

    $ctrl.$onInit = function(){

        var instance = $ctrl.parent.modalInstance;

        $ctrl.items = ['item1', 'item2', 'item3'];

        $ctrl.selected = {
            item: $ctrl.items[0]
        };

        $ctrl.ok = function () {
            instance.close($ctrl.selected);
        };

        $ctrl.cancel = function () {
            instance.dismiss('cancel');
        };

        instance.result.then(function (selectedItem) {
            $ctrl.selected = selectedItem;
        }, function () {
            console.log('Modal dismissed at: ' + new Date());
        });
    };


}

Be carefull because the required controller will only be available after the $onInit.

请小心,因为所需的控制器仅在 $onInit 之后才可用。