如何刷新mui modal自己重构modal属性

近期使用ng重构公司的后台管理系统,类似modal这样的组件,再也不用像以前那样先创建再append(而是由状态驱动);为图方便使用bootstrap的样式和angular-ui的bootstrap组件,然而它的弹出层默认样式是水平居中,垂直方向上并没有;F12之,找到bootstrap.min.css(这里是3.3.5)的相应代码,主要修改以下三个地方,修改后的样子:
第一处(将0改为-50%,相对自身偏移一半):
.modal.in .modal-dialog{-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);-o-transform:translate(0,-50%);transform:translate(0,-50%)}
第二处(原先是relative):
.modal-dialog{position:absolute;width:auto;margin:10px auto;left:0;right:0;top:50%}
@media (min-width:768px){.modal-dialog{width:<span style="color: #px}
&此时modal已经可以垂直居中了:
阅读(...) 评论()简单方法解决bootstrap3 modal异步加载只一次的问题 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了50907字,被249人关注,获得了270个喜欢
简单方法解决bootstrap3 modal异步加载只一次的问题
用过bootstrap3自身的modal的remote属性的人可能都有相同的疑惑:就是点击弹出modal后再次点击会从缓存中加载内容,而不会再次走后台,解决办法就是只要让modal本身的属性发生变化,它便会不会加载缓存。现在可以用一个简单的方法解决此问题:
$('body').on('hidden.bs.modal', '.modal', function () {
$(this).removeData('bs.modal');
在公共的js页面中加入此段代码,即可禁止所有modal加载缓存的内容!
写这篇文章只为能够帮到你^o^
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
写这篇文章只为能够帮到你^o^
选择支付方式:AngularJS: Refactoring a confirmation modal directive [用AngularJS:重构一个确认的模态指令] - 问题-字节技术
AngularJS: Refactoring a confirmation modal directive
用AngularJS:重构一个确认的模态指令
问题 (Question)
I need some advice on refactoring a modal directive I have. I am just getting started with directives, so any other approach to my problem is welcome.
My program needs a confirmation modal, where we can confirm or cancel the desired action. It will appear in many places and needs to be able to have a programmable button. Cancel is consistent in that it will only hide the modal, the confirmation button needs to perform whatever action required.
I am currently using $rootScope to show / hide / configure the modal. Is this a bad idea? Please tell me.
This is what I am working with right now (roughly, as I have cut out a lot of the other unnecessary code):
index.html
&!doctype html&
&html lang="en"&
&title&My App&/title&
&body ng-controller="MenuCtrl"&
&confirmmodal ng-show="$root.confirmModal.isVisible"&&/confirmmodal&
&li&Home&/li&
&li&About&/li&
&li&Contact&/li&
&div ng-view&&/div&
&!-- build:js scripts/main.js --&
&script data-main="scripts/main" src="lib/requirejs/require.js"&&/script&
&!-- endbuild --&
So my modal sits atop the ng-view and can be called from anywhere. It is inside a pseudo global controller, called MenuCtrl.
Here is the modal directive code:
directives.js
/* Confirm Modal */
.directive('confirmmodal', [function() {
restrict: 'E',
templateUrl: 'view/templates/modal-confirm.tpl.html'
It serves as a template for the following code:
modal-confirm.tpl.html
&!-- Confirm Modal Template --&
&div class="overlay"&
&div class="overlay-content extended"&
&span&{{$root.confirmModal.content}}&/span&
&div class="buttons"&
&button class="btn btn-default" ng-click="$root.confirmModal.secondary.action()"&{{$root.confirmModal.secondary.content}}&/button&
&button class="btn btn-primary" ng-click="$root.confirmModal.primary.action()"&{{$root.confirmModal.primary.content}}&/button&
I set a bunch of defaults in the app.run function:
app.run(['$rootScope', function ($rootScope) {
_.extend($rootScope, {
confirmModal: {
isVisible: false,
content: '',
primary: {
action: function() {
console.log('hello world');
content: 'Submit'
secondary: {
action: function() {
$rootScope.confirmModal.isVisible =
content: 'Cancel'
So I've also coded a modal trigger directive, the idea being that I can create different triggers that perform different actions with the modal.
directives.js
/* Resolve Event */
.directive('resolveevent', ['RequestService', '$location', function (RequestService, $location) {
restrict: 'A',
eventtype: '@',
eventid: '@',
index: '@'
controller: ['$scope', function($scope) {
$scope.remove = function(id) {
// remove the event from the events array
$scope.$parent.$parent.$parent.$parent.events.splice(id, 1);
$scope.config = function(config) {
_.extend($scope.$root.confirmModal, config);
$scope.isVisible = function() {
$scope.$apply(function() {
$scope.$root.confirmModal.isVisible =
link: function( $scope, element, attrs ) {
var config = {
content: 'Are you sure you wish to resolve this event?',
primary: {
action: function() {
var config = {
url: '/Events/' + $scope.eventid,
method: 'PUT',
event_status: 'resolved'
cache: false
/* Update event with resolved status */
RequestService.makeApiRequest(config).success(function(response) {
$scope.$root.confirmModal.isVisible =
$scope.remove($scope.index);
content: 'Resolve Event'
element.on('click', function() {
if (!$scope.$root.confirmModal.isVisible) {
$scope.config(config);
$scope.isVisible();
And then I use a button on the view where my ng-repeat is found which is able to trigger the modal:
eventlist.html
&li ng-repeat="event in events"&
&p&Event: {{ event.number }}&/p&
&p&Group: {{ event.group_name }}&/p&
&p&Record Date: {{ event.event_date | moment: 'MM/DD/YYYY h:mm A' }}&/p&
&button resolveevent index="{{$index}}" eventid="{{ event.number }}" class="btn btn-default"&Resolve&/button&
This is what I've got, and it is working, however it seems like overkill, inefficient, and a nightmare to maintain. Can anyone chime in on a way to improve this? I appreciate any help, thanks in advance.
我需要对重构模态指令,我有一些建议。我刚开始使用的指令,所以任何其他办法,我的问题是受欢迎的。我的程序需要一个确认的模态,在那里我们可以确认或取消所需的行动。它会出现在许多地方,需要有一个可编程按钮。取消是一致的,它只会隐藏模式,确认按钮需要执行任何行动要求。我目前正在使用的$rootScope显示/隐藏/配置模式。这是一个坏主意?请告诉我。这就是我现在的工作(大概是,我已经削减了很多不必要的代码):index.html&!doctype html&
&html lang="en"&
&title&My App&/title&
&body ng-controller="MenuCtrl"&
&confirmmodal ng-show="$root.confirmModal.isVisible"&&/confirmmodal&
&li&Home&/li&
&li&About&/li&
&li&Contact&/li&
&div ng-view&&/div&
&!-- build:js scripts/main.js --&
&script data-main="scripts/main" src="lib/requirejs/require.js"&&/script&
&!-- endbuild --&
所以我的模态坐落于ng-view可以称为从任何地方。这是一个伪全局控制器内,称为MenuCtrl。这里是模态指令代码:directives.js/* Confirm Modal */
.directive('confirmmodal', [function() {
restrict: 'E',
templateUrl: 'view/templates/modal-confirm.tpl.html'
它作为下面的代码模板:modal-confirm.tpl.html&!-- Confirm Modal Template --&
&div class="overlay"&
&div class="overlay-content extended"&
&span&{{$root.confirmModal.content}}&/span&
&div class="buttons"&
&button class="btn btn-default" ng-click="$root.confirmModal.secondary.action()"&{{$root.confirmModal.secondary.content}}&/button&
&button class="btn btn-primary" ng-click="$root.confirmModal.primary.action()"&{{$root.confirmModal.primary.content}}&/button&
我把一堆中的缺省值app.run功能:app.jsapp.run(['$rootScope', function ($rootScope) {
_.extend($rootScope, {
confirmModal: {
isVisible: false,
content: '',
primary: {
action: function() {
console.log('hello world');
content: 'Submit'
secondary: {
action: function() {
$rootScope.confirmModal.isVisible =
content: 'Cancel'
所以我也编码模式触发指令,这样我可以创建不同的触发器执行不同的动作与模态。directives.js/* Resolve Event */
.directive('resolveevent', ['RequestService', '$location', function (RequestService, $location) {
restrict: 'A',
eventtype: '@',
eventid: '@',
index: '@'
controller: ['$scope', function($scope) {
$scope.remove = function(id) {
// remove the event from the events array
$scope.$parent.$parent.$parent.$parent.events.splice(id, 1);
$scope.config = function(config) {
_.extend($scope.$root.confirmModal, config);
$scope.isVisible = function() {
$scope.$apply(function() {
$scope.$root.confirmModal.isVisible =
link: function( $scope, element, attrs ) {
var config = {
content: 'Are you sure you wish to resolve this event?',
primary: {
action: function() {
var config = {
url: '/Events/' + $scope.eventid,
method: 'PUT',
event_status: 'resolved'
cache: false
/* Update event with resolved status */
RequestService.makeApiRequest(config).success(function(response) {
$scope.$root.confirmModal.isVisible =
$scope.remove($scope.index);
content: 'Resolve Event'
element.on('click', function() {
if (!$scope.$root.confirmModal.isVisible) {
$scope.config(config);
$scope.isVisible();
然后我用一个按钮在看我ng-repeat发现这是能够触发模式:eventlist.html&li ng-repeat="event in events"&
&p&Event: {{ event.number }}&/p&
&p&Group: {{ event.group_name }}&/p&
&p&Record Date: {{ event.event_date | moment: 'MM/DD/YYYY h:mm A' }}&/p&
&button resolveevent index="{{$index}}" eventid="{{ event.number }}" class="btn btn-default"&Resolve&/button&
这是我所得到的,这是工作,但是它似乎矫枉过正,效率低下,并保持一个噩梦。任何人都可以参与的方式来提高呢?我感谢任何帮助,谢谢。
最佳答案 (Best Answer)
You can have a look at the bootstrap-ui project :
If you're using Bootstrap 3, be careful about the templates, and use the version without them. You can download bootstrap3 compliant templates here :
你可以在引导UI项目一看:如果你使用自举3,对模板仔细,并使用版本没有他们。你可以在这里下载bootstrap3兼容的模板:
答案 (Answer) 2
My method might not be according to best practises, but I usually end up creating dedicated service that both has access to modal's scope and manipulates dom. Think of it as self injecting directive.
Here's the modal's container html (uses bootstrap's styling):
&div class="modal-backdrop"&&/div&
&div class="modal fade"&
&div class="modal-dialog" ng-style="{width: width}"&
&div class="modal-content"&
&div class="modal-header"&
&button type="button" class="close" ng-click="close()" aria-hidden="true"&&&/button&
&h4 class="modal-title"&{{title}}&/h4&
&div class="modal-body"&
&div class="modal-footer"&
&button ng-repeat="(name, callback) in buttons" type="button" ng-click="callback()"&{{name}}&/button&
Then there's pseudo code of the DialogService:
.service('DialogService', function($compile, $http, $rootScope) {
this.open = function(options) {
//options contain various properties
//e.g. title, width, template or templateUrl, button map with callbacks
loadModalContainer()
.then(loadModalBody)
.then(init);
function init() {
modal = $('body').append(containerHtml).find('.modal');
modal.append(bodyHtml);
scope = (options.scope || $rootScope).$new();
if (options.controller) $controller(options.controller, {$scope: scope});
$compile(modal)(scope);
listenForEscKey();
function close() {
//clean up event listeners
if (options.onClose) options.onClose();
scope.$destroy();
$('body').find('.modal,.modal-backdrop').remove();
Of course, because of the async nature of the service, you have to implement some auto-close logic if second modal pops-up. From there is really easy, you can define concrete dialogs as separate services to abstract away the details:
.service('TermsModal', function(DialogService) {
this.open = function(acceptCallback, declineCallback, scope) {
DialogService.open({
templateUrl: '',
width: '',
buttons: {
accept: acceptCallback,
decline: declineCallback
scope: scope
Then from any controller you can open modal with an one-liner: TermsModal.open(acceptCallback, declineCallback, $scope)
There are several issues. First of all, it would be great to use transclusion, since now modal's child scope is littered with title, buttons, width properties.
Another thing is that I pass around modal body's width, but that's just my laziness (I cannot style bootstraps modal body width properly since it's hardcoded).
Also, I pass around local scopes from controllers because very often modal's body content is in one or another way related to the controller that invokes the modal. If, say, we have ItemController with item as scope property and we have an edit button to edit item's value in a modal, the child scope has to know about the model it's dealing with. So either it's passing around scope or passing needed values directly in options. I prefer scope because that gives more flexibility and with child scope intialization it is really hard to mess up orginal model.
All in all, the power and flexibility this set-up gives justifies the fact that service is messing a bit with the DOM. Your rootScope becomes free of global state (the service manages its own state without giving details to the outside world) and your main template is free of modal partials/directives/whatever that may or may not be used.
我的方法不可能根据最好的练习,但是我通常最终建立专门的服务,已获得模态的范围和操作DOM。认为这是自注入指令。这里的模态的容器(使用HTML引导的造型):&div class="modal-backdrop"&&/div&
&div class="modal fade"&
&div class="modal-dialog" ng-style="{width: width}"&
&div class="modal-content"&
&div class="modal-header"&
&button type="button" class="close" ng-click="close()" aria-hidden="true"&×&/button&
&h4 class="modal-title"&{{title}}&/h4&
&div class="modal-body"&
&div class="modal-footer"&
&button ng-repeat="(name, callback) in buttons" type="button" ng-click="callback()"&{{name}}&/button&
然后有伪代码的dialogservice:.service('DialogService', function($compile, $http, $rootScope) {
this.open = function(options) {
//options contain various properties
//e.g. title, width, template or templateUrl, button map with callbacks
loadModalContainer()
.then(loadModalBody)
.then(init);
function init() {
modal = $('body').append(containerHtml).find('.modal');
modal.append(bodyHtml);
scope = (options.scope || $rootScope).$new();
if (options.controller) $controller(options.controller, {$scope: scope});
$compile(modal)(scope);
listenForEscKey();
function close() {
//clean up event listeners
if (options.onClose) options.onClose();
scope.$destroy();
$('body').find('.modal,.modal-backdrop').remove();
当然,由于服务的异步性,如果第二模态弹出你要执行一些自动关闭逻辑。从那里,真的是很容易的,你可以定义具体的对话作为单独的服务抽象掉的细节: .service('TermsModal', function(DialogService) {
this.open = function(acceptCallback, declineCallback, scope) {
DialogService.open({
templateUrl: '',
width: '',
buttons: {
accept: acceptCallback,
decline: declineCallback
scope: scope
然后从任何控制器,你可以打开一个线性模态:TermsModal.open(acceptCallback, declineCallback, $scope)有几个问题。首先,它是使用嵌入包含巨大的,因为现在的模态的孩子范围到处都是title, buttons, width性能另一件事是,在身体的宽度,通过模态我,但那只是我的懒惰(我不能风格白手起家模态体宽度适当因为这是硬编码)。另外,我通过在局部作用域控制器因为经常模态的主体内容是在一种或另一种方式控制器调用模型相关。如果说,我们有itemcontroller,item范围属性和我们有一个编辑按钮以模式编辑项目的价值,孩子范围已经知道模型的处理。所以无论是传递范围或通过直接选择所需要的值。我喜欢范围,提供了更大的灵活性和范围初始化的孩子真是一团糟,原始模型。总之,力量和灵活性,这种设置提供了证明的事实,服务是在一位与DOM。你的rootscope成为免费的全局状态(服务管理自己的国家没有提供细节,到外面的世界),你的主要模板的自由模态的谐音/指令/什么,可能会或可能不会被使用。
答案 (Answer) 3
I have created a small confirmation directive which, opens a modal and executes the code you want, if the modal is confirmed:
&button type="button" class="btn btn-default"
nait-confirm-click
confirm="Do you really want to remove this record?"
confirm-if="user.disabled == true"
do="remove(user)"&
.module('xyz', ['ui.bootstrap'])
.directive('naitConfirmClick', function($modal, $parse) {
restrict: 'EA',
link: function(scope, element, attrs) {
if (!attrs.do) {
// register the confirmation event
var confirmButtonText = attrs.confirmButtonText ? attrs.confirmButtonText : 'OK';
var cancelButtonText = attrs.cancelButtonText ? attrs.cancelButtonText : 'Cancel';
element.click(function() {
// action that should be executed if user confirms
var doThis = $parse(attrs.do);
// condition for confirmation
if (attrs.confirmIf) {
var confirmationCondition = $parse(attrs.confirmIf);
if (!confirmationCondition(scope)) {
// if no confirmation is needed, we can execute the action and leave
doThis(scope);
scope.$apply();
template: '&div class="modal-body"&' + attrs.confirm + '&/div&'
+ '&div class="modal-footer"&'
'&button type="button" class="btn btn-default btn-naitsirch-confirm pull-right" ng-click="$close(\'ok\')"&' + confirmButtonText + '&/button&'
'&button type="button" class="btn btn-default btn-naitsirch-cancel pull-right" ng-click="$dismiss(\'cancel\')"&' + cancelButtonText + '&/button&'
+ '&/div&'
.result.then(function() {
doThis(scope);
scope.$apply()
Now, if you click on the button with the nait-confirm-click it opens a modal with two buttons and the text you have passed by the confirm attribute. If you click the cancel button, nothing will happen. If you confirm by clicking "OK", the expression, which you have passed by the do attribute, will be executed.
If you pass an expression in the optional confirm-if attribute, the modal will only be opened if the expression is true. If the expression is false, the action will be executed without asking.
I hope this snippe)
我创建了一个小的确认指令,打开一个模态和执行你想要的代码,如果模态确认:app.html&button type="button" class="btn btn-default"
nait-confirm-click
confirm="Do you really want to remove this record?"
confirm-if="user.disabled == true"
do="remove(user)"&
script.jsangular
.module('xyz', ['ui.bootstrap'])
.directive('naitConfirmClick', function($modal, $parse) {
restrict: 'EA',
link: function(scope, element, attrs) {
if (!attrs.do) {
// register the confirmation event
var confirmButtonText = attrs.confirmButtonText ? attrs.confirmButtonText : 'OK';
var cancelButtonText = attrs.cancelButtonText ? attrs.cancelButtonText : 'Cancel';
element.click(function() {
// action that should be executed if user confirms
var doThis = $parse(attrs.do);
// condition for confirmation
if (attrs.confirmIf) {
var confirmationCondition = $parse(attrs.confirmIf);
if (!confirmationCondition(scope)) {
// if no confirmation is needed, we can execute the action and leave
doThis(scope);
scope.$apply();
template: '&div class="modal-body"&' + attrs.confirm + '&/div&'
+ '&div class="modal-footer"&'
'&button type="button" class="btn btn-default btn-naitsirch-confirm pull-right" ng-click="$close(\'ok\')"&' + confirmButtonText + '&/button&'
'&button type="button" class="btn btn-default btn-naitsirch-cancel pull-right" ng-click="$dismiss(\'cancel\')"&' + cancelButtonText + '&/button&'
+ '&/div&'
.result.then(function() {
doThis(scope);
scope.$apply()
现在,如果你点击的按钮NAIT确认一下它打开一个模态和两个按钮,你已经通过了文本确认属性。如果您单击“取消”按钮,什么都不会发生。如果你确认通过点击“好的”,表达,你通过了做属性,将被执行。如果你通过表达可选确认属性,该模型将表达式为真时打开。如果表达式为假,将执行的行动没有问。我希望这段代码将帮助别人;)
本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:}

我要回帖

更多关于 psv如何重构数据库 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信