简体   繁体   English

如何在角度1.5中使用ui.bootstrap.modal的角度分量?

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

I'd like to use angular component with ui.bootstrap.modal. 我想在ui.bootstrap.modal中使用angular组件。 angular version is 1.5. 角度版本是1.5。
I tried to use like below. 我尝试使用如下。

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 Provider although modal window is open. 当我执行parentController.openModal() ,我得到了$ injector:unpr未知提供程序的错误,尽管模态窗口是打开的。
Is there a way to use angular component with ui.bootstrap.modal? 有没有办法在ui.bootstrap.modal中使用角度组件? If you need more information, please let me know that. 如果您需要更多信息,请告诉我。
Thank you. 谢谢。

EDIT 编辑
I've got a way to use component with ui.bootstrap.modal from Renato Machado, Thanks Renato. 我有办法使用Renato Machado的ui.bootstrap.modal组件,感谢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以常规方式打开(只需在$uibModal.open({})设置控制器和模板),模态包含具有通常要使用的逻辑的组件。
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. 它很容易共同化。

EDIT: As of UI Bootstrap 2.1.0 there is native support for component in bootstrap modals. 编辑:从UI Bootstrap 2.1.0开始,对bootstrap模式中的组件有本机支持。 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. 看起来在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'
            });
        };
    }],
});

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. 由于您声明模板是一个组件,因此$ scope。$ parent将始终指向模式实例。 Allowing you to access the $close() function. 允许您访问$ 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 guide to create the component. 只是在旁注,我正在使用此结构样式指南来创建组件。

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文档有点稀疏,但它们将& binding的用法显示为函数包装器: https//docs.angularjs.org/guide/component

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之后使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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