给我你的怀抱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:
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:
javascript
function 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.