angularjs使用lhgdialog做对话框控件

关于这条“军规”,我们就不要浪费口舌了,angular-strap等很多库扩展的做法,都没有一下子舍弃jquery的生态圈

Don't even use jQuery. Don't even include it 

我这篇blog主要是以一个示例呼应下另外一些朋友的blog——angularjs与其他类库的协作

lhgdialog是一个很优秀的对话框的js库,提供jquery插件形式,我们项目上用起来很方便。如果用angular纯模型控制的方式去做dialog,需要大量的css控制属性,其中drop/resize等比起现有的jquery都算从头重写,当然费时费力,所以我们还是采取结合jquery实现。

因为open一个dialog,底层是clone一段dom到body下,用定位去实现的,对于这种动态创建的dom,angular本身在第一次bootstrap编译时候是没有双向绑定特性的,这要借助强大的$compile这个服务

为了在应用层(controller/model)的代码少点jquery的侵入,所以做成了指令(用指令还会引发一些其他问题,在此不表)——

md.directive('uiDialog2', ['$parse', '$compile', 'ng.config', 'uiLog', 'safeApply', function($parse, $compile, conf, log, safeApply){
'use strict';
return {
	restrict: 'A',
	link: function(scope, el, attrs){
		var opts = scope.$eval(attrs.uiDialog2) || {};
		log.i('Compile dialog2 ui : ');
		log.i(opts);

		if(!opts.showModel || !opts.dialogId){
			log.w('No show model and dialog id given!');
			return;
		}

		// lhgdialog properties
		var props = {};
		if(ag.isObject(conf.dialog2)){
			ag.extend(props, conf.dialog2);
		}
		props.id = opts.dialogId;
		props.content = el.html();
		props.init = function(){
			// in watch
			$compile($('.ui_content:first'))(scope);
		};
		props.close = function(){
			// use close in dialog toolbar will execute twice
			// use button in dialog user defined will execute once which trigger by watch list
			var getter = $parse(opts.showModel);
			var isShow = getter(scope);
			if(isShow){
				var setter = getter.assign;
				// trigger watch again
				safeApply(scope, function(){
					setter(scope, false);
				});
			}
		};

		// over write
		if(angular.isDefined(opts.lock))
			props.lock = opts.lock;
		if(angular.isDefined(opts.drag))
			props.drag = opts.drag;
		if(angular.isDefined(opts.fixed))
			props.fixed = opts.fixed;
		if(angular.isDefined(opts.resize))
			props.resize = opts.resize;
		if(opts.width)
			props.width = opts.width;
		if(opts.height)
			props.height = opts.height;
		if(opts.left)
			props.left = opts.left;
		if(opts.top)
			props.top = opts.top;

		scope.$watch(opts.showModel, function(val){
			// show
			if(val){
				$.dialog(props);
			}else{
				// hide
				var target = $.dialog.list[opts.dialogId];
				if(target)
					target.close();
			}
		});
	}
};
}]);

html/js里用法就很简单

var myModule = angular.module('myModule', ['ng.ui']);
	myModule.controller('MyCtrl', function($scope){
		$scope.detail = {name: 'kerry'};
		$scope.isDialogShow = false;

		$scope.open = function(){
			$scope.detail = {name: ''};
			$scope.isDialogShow = true;
		};
		$scope.close = function(){
			$scope.isDialogShow = false;
		};
	});

	window.angular.bootstrap(document, ['myModule']);

html代码如下

<body ng-controller="MyCtrl">
<div class="container_12">
	<button class="btn btn-blue" ng-click="open()">Open</button>
	<br />
	{{isDialogShow}}
</div><!-- /.container_12 -->

<div ui-dialog2="{showModel: 'isDialogShow', dialogId: 'dialogA', lock: true}" title="DIALOG" 
	style="display: none;">
	<form name="detailForm">
	<input ng-model="detail.name" ui-valid="r int" />
	</form>
	<br />
	{{detailForm.$valid}}
	<br />
	<button class="btn btn-red" ng-click="close()">Close</button>
</div>

</body>

当然,前提是你html里要引入jquery/lhgdialog的js

相关推荐