我已经在SO和Google上对这个问题进行了一些研究。但没有一个答案符合我的目的。
我在HTML视图中有一个模态,用于在我的应用中显示弹出通知。
我希望在我通过的div
模式中显示一些按钮(' OK','取消''登录'等等)动态地作为JS对象。作为键的按钮的名称和作为值的回调函数。
示例:
{
"Login": function(){....}
}
{
"OK": function(){...},
"Cancel": function(){...}
}
现在我将这种对象传递给我在视图中的弹出模式的控制器中的方法showPopup(message, buttonMap)
。
message
是弹出窗口上的显示消息,buttonMap
是示例中的对象。
控制器:
angular.module('core').controller('PopupController', ['$rootScope', 'LogService', 'MessageHandlerService',
function ($rootScope, LogService, MessageHandlerService) {
var ctrl = this;
ctrl.buttonMap = {};
ctrl.btnWidth = 100;
$rootScope.$on('popup', showPopup);
function showPopup (event, message, buttonMap) {
$('#genericModalDialog .popup-content p').html(message);
ctrl.buttonMap = buttonMap;
var numberOfButtons = Object.keys(buttonMap).length;
ctrl.btnWidth = (100 - numberOfButtons*2)/numberOfButtons;
$("#genericModalDialog").modal('show');
}
ctrl.callbackFor = function callbackFor(key) {
ctrl.buttonMap[key].call(null);
};
}
]);
服务
angular.module('core').service('PopupService', ['$rootScope', 'LogService', 'CacheService', 'MessageHandlerService',
function ($rootScope, LogService) {
this.isPopupShown = function (){
return $("#genericModalDialog").hasClass('in');
}
this.showPopup = function (message, btnMap){
$rootScope.$broadcast('popup', message, btnMap);
}
this.closePopup = function (){
$("#genericModalDialog").modal('hide');
}
}
]);
查看:
<div ng-controller="PopupController as popupCtrl" class="modal fade" id="genericModalDialog" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="vertical-alignment-helper">
<div class="modal-dialog vertical-align-center" style="width:94%;">
<div class="modal-content">
<div class="modal-body">
<br/><br/>
<div class="popup-content">
<p align="center"></p><br/>
<div class="popup-action">
<button type="button" class="btn" style="width:{{popupCtrl.btnWidth}}%; margin:1%" ng-repeat="(buttonName, callBack) in popupCtrl.buttonMap" ng-click="popupCtrl.callbackFor(buttonName)">{{buttonName}}</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
由于我不想在每个其他控制器/服务中实例化PopupController
,我已经编写了一个名为PopupService
的服务,该服务有一个可以调用的方法$broadcast
"popup"
1}} $rootscope
上名为PopupController
的事件,我正在 Downloading install package from
https://downloads.wordpress.org/plugin/types.1.8.11.zip…
Unpacking the package…
Installing the plugin…
The package could not be installed. No valid plugins were found.
Plugin install failed.`
处理此事件。在这种情况下,一切都被触发并正常工作。我面临的唯一问题是在UI上呈现弹出窗口的延迟,我一看到弹出窗口就看到了消息但是按钮的渲染非常慢(大约3秒),这是因为加载了一些其他网页在后台。
当我在互联网上搜索这个问题时,我也发现这个总体设置可以改为指令,动态内容的渲染(在这种情况下是弹出窗口和按钮)可以放在链接功能中指令。
我看到的另一种方法是直接处理服务中的DOM操作,这当然不是一个好方法。
我是否错过任何其他方法或解决此问题?
所有我想知道的是最好的方法,处理这种以编程方式和设计明智的方式。
如果我不清楚请告诉我。我会尝试再次解释这个问题。
答案 0 :(得分:0)
指令将是DOM操作的更好选择。另外,您应该考虑将jQuery对话框的用法更改为https://angular-ui.github.io/bootstrap/#/modal。
Here就是一个如何做到的例子:
1)创建指令
DoAsyncNetworkIO
2)创建modalInstance指令
static object mutex = new object();
static Task currentTask;
async Task Fetch()
{
lock(mutex)
{
if(currentTask != null)
return currentTask;
}
currentTask = DoAsyncNetworkIO();
await currentTask;
lock(mutex)
{
var task = currentTask;
currentTask = null;
return task;
}
}
3)创建指令模板 app.directive('myModal', function() {
return {
restrict: 'E',
scope: {
items: "=",
message: "="
},
replace: true,
templateUrl: "directiveTemplate.html",
controller: function($scope, $uibModal, $log) {
$scope.open = function(size) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
},
message: function() {
return $scope.message;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.button = selectedItem.name;
$scope[selectedItem.callback](selectedItem.name);
});
};
}
}
});
app.controller('ModalInstanceCtrl', function($scope, $uibModalInstance, items, message) {
$scope.items = items;
$scope.message = message;
$scope.close = function(item) {
$uibModalInstance.close(item);
};
});
4)创建弹出式模板&#39; myModalContent.html&#39;
directiveTemplate.html
5)定义你的控制器,你将在弹出窗口中显示按钮列表和消息(为了演示目的,这里有两个不同的项目列表和两个消息)
<div>
{{buttonClicked}}
<br> {{button}}
<button type="button" class="btn btn-default" ng-click="open('sm')">{{message}}</button>
</div>
并为了您所需的指令:
{{message}}
<button ng-repeat="item in items" type="button" class="btn btn-default" ng-click="close(item)">{{item.name}}</button>
如果您从不同的角度应用程序实例访问指令,那么只需将指令应用程序注入所需的应用程序(确保指令和模态实例具有自己定义的模块ex: app.controller('ModalDemoCtrl', function($scope) {
$scope.message = "modal 1";
$scope.items = [{
name: 'item1',
callback: "test1"
}, {
name: 'item2',
callback: "test2"
}, {
name: 'item3',
callback: "test3"
}];
$scope.message2 = "modal 12222";
$scope.items2 = [{
name: 'item1222',
callback: "test1"
}, {
name: 'item2222',
callback: "test2"
}, {
name: 'item3222',
callback: "test3"
}];
$scope.test1 = function(message) {
$scope.buttonClicked = "clicked test1";
}
$scope.test2 = function(message) {
$scope.buttonClicked = "clicked test2";
}
$scope.test3 = function(message) {
$scope.buttonClicked = "clicked test3";
}
});
,这是一个在此示例之后用于注入其他模块:<div ng-controller="ModalDemoCtrl">
<my-modal items="items" message="message"></my-modal>
</br>
<my-modal items="items2" message="message2"></my-modal>
</div>
)