通过项目中定位的一个问题:学习ionic框架$ionicPopover的使用以及注意事项

本文介绍了在项目中遇到的关于$ionicPopover的问题,当使用jquery无法选中popover内的元素时,通过深入理解popover的原理和ionic框架的工作方式,找到了问题的关键在于popover未被初始化并插入到DOM中。解决方案是先显示再隐藏popover,确保模板被正确加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

popover是手机上很常用的控件,ionic框架提供了$ionicPopover来创建popover对象。为了学习ionic和popover,你可能需要了解一些基本知识。这些基本知识,也是我在修改项目中一个关于popover问题的时候总结学习的。

1.引入ionic框架的时候遇到了一个问题Invalid regular expression,有了这篇文章

2.popover使用到了javascript模板技术,关于模板简单地作了个总结,有了这篇文章

3.学习<template>的时候,了解了什么是文档碎片DocumentFragment,有了这篇文章

4.简单对如何引入ionic框架以及常用的一些资源url,有了这篇文章


现在我来描述下项目中遇到的那个问题,有了上面的知识储备,这个问题就很好理解了,甚至是显而易见的。不过最开始我对上面这些知识了解不深,所以解决这个问题也是费了一些工夫。


我们的项目会自定义很多控件,一个页面由很多个控件组成,每个控件都有一个dftype属性来表示控件的类型。



页面加载完成后,我们会遍历所有的dftype组件,并创建其对象(dftype的值就对应js中的类)。然后用一个全局变量components记录当前页面包含的所有控件。每一个页面都是一个单独的angularjs模块,页面下的每个控件都有自己的ng-controller。

// $range是整个页面对应的jquery包装对象
var $list = $range.find("*[dftype]");
$list.each(function() {
	var type = this.getAttribute("dftype");
	var elementId = this.getAttribute("id");
	eval("var cp = new " + type + "(elementId)");
	var sid = cp.getSid();
	components[sid] = cp;
});

// 启动angularjs模块
angular.bootstrap(E(id), [id]);


下面是一个按钮控件的js代码:每个控件会根据id,使用jquery的id选择器获取配置信息。

define(["spl/util", "widget/mspl/button/Button"], function() {
	
    Nf.mspl.button.ServiceButton = function(id) {
        this.id = id;
		// 根据id获取配置信息
        var json = $.trim($E(id).attr("json"));
        this.options = JSON.parse(json);
        this.init();
    }
	......
});


页面footer使用了popover,点击的时候才会弹出popover。



问题是:页面bootstrap的时候,无法初始化popover上面的Depart、Suspend等按钮控件。问题原因很简单:使用jquery选择器$range.find("*[dftype]")的时候无法选中这些在popover中的控件


现在我们研究下ionic的popover一些特性,参考$ionicPopover文档,可以很容易自己添加一个popover。

<html>
  <head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
	<script src="jquery-1.11.1.min.js"></script>
    <script src="./1.1.1-release/js/ionic.bundle.js"></script>
	<link rel="stylesheet" type="text/css" href="./1.1.1-release/css/ionic.css" />
	<style>
		.left{margin-left:200px;}
	</style>
	
	<script>
		var testModule = angular.module('testApp', ['ionic']);
		testModule.controller('MyController', function($scope, $ionicPopover) {
			/* 方式1: fromTemplate() method
			var template = '<ion-popover-view><ion-header-bar> <h1 class="title">My Popover Title</h1> </ion-header-bar> <ion-content> Hessssllo!</ion-content></ion-popover-view>';

			$scope.popover = $ionicPopover.fromTemplate(template, {
				scope: $scope
			});
			*/
			
			// 方式2: fromTemplateUrl() method
			$ionicPopover.fromTemplateUrl('my-popover.html', {
				scope: $scope
			}).then(function(popover) {
				$scope.popover = popover;
			});
			
			$scope.eventPopover = function($event) {
				
				$scope.popover.show($event);
			};
  
			$scope.elementPopover = function(id) {
				$scope.popover.show($("#"+id));
			};
  
			$scope.closePopover = function() {
				$scope.popover.hide();
			};
			
			//Cleanup the popover when we're done with it!
		    $scope.$on('$destroy', function() {
				$scope.popover.remove();
		    });
			
			// Execute action on hide popover
			$scope.$on('popover.hidden', function() {
				// Execute action
			});
			
			$scope.$on('popover.shown', function() {
				// Execute action
				alert(1);
			});
			
			// Execute action on remove popover
			$scope.$on('popover.removed', function() {
				// Execute action
		  });
	});//end for controller
       

	$(function(){
		angular.bootstrap($("#body"), ["testApp"]);
	})
	</script>
</head>

<body id="body" ng-controller="MyController">
  
	<ion-header-bar class="bar-positive">
		<a class="button button-icon icon ion-more" id="left"></a>
			<h1 class="title">bar-positive</h1>
		<a class="button button-icon icon ion-more" id="right"></a>
	</ion-header-bar>
  
	<ion-content class="has-header" style="background-color: #ebebeb;">
			<button class="left" ng-click="elementPopover('left')">left1</button>
			<button ng-click="eventPopover($event)">left2</button>
			<button ng-click="eventPopover($event)">right1</button>
			<button ng-click="elementPopover('right')">right2</button>
	</ion-content>
	
	<ion-footer-bar class="bar-balanced">
		<div class="title">Footer</div>
	</ion-footer-bar>
</body>
</html>

<script id="my-popover.html" type="text/ng-template">
	  <ion-popover-view>
		<ion-header-bar>
		  <h1 class="title">My Popover Title</h1>
		</ion-header-bar>
		<ion-content>
		  Hello!
		</ion-content>
	  </ion-popover-view>
</script>	
	

运行上面的html,F12可以看到生成的html代码如下。ioinic给我们的元素添加了一些grade-a等熟悉。注意<script>标签存放的模板并没有发生变化。



现在我们点击上面的按钮,会弹出popover,之后在点击空白处隐藏popover,生成的html如下。

可以看到:ionic将<script>下的模板插入到页面的DOM树中了。


现在回到我们在项目中遇到的问题,就很好理解了。页面初始化的时候,并没有弹出popover,所以我们并没有初始化popover。ionic不会将<script>下的模板内容插入到DOM树下,而jquery是不能选中<script>下的元素的。解决方案就很简单了:在页面初始化调用fromTemplateUrl的时候,先显示popover再隐藏即可。这样就能够触发ionic将<script>下的模板插入到DOM树,这样jquery就能选中了。

$ionicPopover.fromTemplateUrl('my-popover.html', {
	scope: $scope
}).then(function(popover) {
	$scope.popover = popover;
	$scope.popover.show($("#body"));
	$scope.popover.hide();
});


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值