search

Home  >  Q&A  >  body text

angular.js - angularjs $modal的用法

如何使用angularjs $modal编写一个公用的弹框插件?望详解,谢谢。

PHPzPHPz2742 days ago721

reply all(1)I'll reply

  • 给我你的怀抱

    给我你的怀抱2017-05-15 16:55:44

    I'll tell you an idea, but I won't explain it in detail, because I don't like to reach out to others... I'll give you the plan, at least use your brain to think about it.

    First of all, the following code does not use ui-bootstrap's $modal, but ng-strap's $modal. The reason is that I think the code quality of the latter is better than the former, but the latter is relatively new and the API is not as complete as the former. Therefore, you need to have relatively strong hands-on skills, but this has nothing to do with the expansion of $modal service that I will talk about next.

    Secondly, you must consider these issues before extending a public $modal service:

    1. What can be reused? Which ones need to be (possibly) newly specified each time? (templates, parameters, methods, etc.)
    2. What is the expected calling method? What does the return result look like?
    3. How high are the scalability and flexibility requirements?

    There is no clear answer to these questions at the beginning, but you need to simulate an answer in your mind, because it will determine how to write your service.

    The first step is to prepare the default parameters; these are the parameters provided by the original $modal. First set an initial state (according to your own needs)

    javascript// 可以在入口模块的 .config 里做
    angular.extend($modalProvider.defaults, {              
        animation: 'am-flip-x',                            
        container: 'body',                                 
        templateUrl: 'components/angular-strap/modal.html'
    })                                                     
    

    Step 2: Write the attribute extension code of the new service; so that the new service can have the same attribute extension capabilities as the original $modal

    javascript// 一样,放在某个某块的 config 里
    .config(function ConfirmModalConfig($modalProvider, ConfirmModalProvider) {
        ConfirmModalProvider.defaults = angular.extend(
            $modalProvider.defaults, ConfirmModalProvider.defaults
        )
    })
    

    Then there is the definition of ConfirmModal, and the final return is $promise, so that the caller can expand his or her business logic; I added some comments at the key points, and the rest can be understood by yourself:

    javascriptfunction ConfirmModal() {
        // 新服务的默认参数,允许覆盖
        this.defaults = {
            html: true,
            templateUrl: 'components/angular-strap/confirm.html',
            contentTemplate: 'components/angular-strap/confirm-modal.html'
        }
    
        this.$get = function($q, $modal) {
            return {
                // 只需一个 public method 足够了
                open: function _openConfirmModal(parentScope, options) {
                    // 把调用者的 $scope 传进来,生成新的 $scope 给自己,实现 $scope 继承
                    // 最大的用处:可以在 $modal 的模版里直接是用 parent $scope 里的属性和方法
                    var _scope = parentScope.$new()
    
                    // 给新 $scope 一个 namespace,等价于 angular 的 controller as 语法
                    _scope.modalModel = {}
    
                    // 合并默认参数和用户传递的参数
                    var _options = angular.extend(_.clone(this.defaults), options)
                    _options.scope = _scope
    
                    // 创造 modal 实例
                    var _modal = $modal(_options)
    
                    // 返回 promise,默认给模版绑定两个方法,一个用于确认,一个用于取消
                    // 如需要更多方法,则可以在 contentTemplate 里调用 parent $scope 的方法
                    // @params immediateHide: 布尔,用于指明触发默认绑定方法后是自动关闭 $modal,
                    // 还是留给调用者在 .then 里手动关闭
                    return $q(function(resolve, reject) {
                        _scope.modalModel.confirm = function(data, immediateHide) {
                            if (immediateHide) {
                                _modal.hide()
                                resolve({data: data})
                            } else resolve({data: data, modal: _modal})
                        }
    
                        _scope.modalModel.cancel = function(reason, immediateHide) {
                            if (immediateHide) {
                                _modal.hide()
                                reject({reason: reason})
                            } else reject({reason: reason, modal: _modal})
                        }
                    })
                }.bind(this)
            }
        }
    }
    

    Call example:

    javascript// 在某处,通常是 controller 或 directive
    function SomeWhereController(ConfirmModal, Something, $state) {
        var vm = this
    
        vm.delete = function(something) {
            ConfirmModal.open($scope, { title: '确定要删除吗?' })
            .then(function(result) { return Something.delete(something.id) })
            .then(function(response) { $state.reload($state.current) })
            .catch(console.error.bind(console))
        }
    }
    

    For templates, just refer to the original $modal and rewrite it yourself. The code is available on github, that’s it.

    reply
    0
  • Cancelreply