Ionic-wechat项目边开发边学(三):自定义样式,指令,服务
摘要
上一篇文章主要介绍了一个ionic项目的标准目录结构,header标签的使用,以及页面之间的切换。这篇文章实现的功能有: 消息数据的获取, 消息列表的展示, 消息标为已读/未读, 主要涉及的到的知识点有:
- ion-list的使用
- ion-popup的使用
- 通过sass自定义样式
- localStorage的使用
- 自定义指令和服务
先看效果图:

功能分析
在开始之前, 最好先思考一下消息页面的主要功能, 和大概如何实现. 这样后面写程序才不会乱. 我大体列了一下

消息的数据暂时用localStorage存储, 但这不是好的方式, localStorage可能会被文件清理掉, 后面会换sqlite存储
页面布局
首先在'tab-message.html'中添加聊天消息的布局
<ion-view>
<ion-content on-swipe-left="onSwipeLeft()">
<!--这里的rj-close-back-drop是自定义指令, 后面会讲是干嘛的-->
<ion-list rj-close-back-drop>
<ion-item class="item-avatar" on-hold="popupMessageOpthins($index)" rj-hold-active ng-repeat="message in messages">
<img ng-src="{{message.pic}}">
<!--这个就是来了新消息, 头像上的小红数字-->
<span class="rj-sm-red-icon" ng-show="message.showHints"><p ng-bind="message.noReadMessages"></p></span>
<h2 ng-bind="message.name"></h2>
<p class="rj-list-p" ng-bind="message.lastMessage.content"></p>
<span class="rj-push-right" ng-bind="message.lastMessage.time"></span>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
大家在试这个的时候, 由于'messages'还未定义, 先不绑定, 用实际的值代替,像这样
<img src="img/ben.png">
<span class="rj-sm-red-icon"><p>1</p></span>
<h2>小王</h2>
<p class="rj-list-p">你在干什么?</p>
<span class="rj-push-right">12:30</span>
这样就能看到效果了

自定义样式
可以看到上图有点丑, 需要我们自己修改样式, 可以自己添加css文件link进来, 但官方推荐使用sass的方式修改, 关于sass的语法, 可以看这个, 看完就差不多可以了.
首先在项目目录下,运行命令
$ionic setup sass
$ionic serve
运行以后, 就会对scss/ionic.app.scss文件监控, 有修改, 会自动编译该文件, 输出到css/ionic.app.css
所以你每次修改保存scss文件后, 浏览器会看到实时的效果, 非常方便.
打开scss/ionic.app.scss文件, 如下
/*
To customize the look and feel of Ionic, you can override the variables
in ionic's _variables.scss file.
For example, you might change some of the default colors:
$light: #fff !default;
$stable: #f8f8f8 !default;
$positive: #387ef5 !default;
$calm: #11c1f3 !default;
$balanced: #33cd5f !default;
$energized: #ffc900 !default;
$assertive: #ef473a !default;
$royal: #886aea !default;
$dark: #444 !default;
*/
// The path for our ionicons font files, relative to the built CSS in www/css
$ionicons-font-path: "../lib/ionic/fonts" !default;
可以看到官方预定义的颜色几个颜色, 如果要修改预定义的颜色, 直接修改这里就可以了.
我们自己的样式, 直接在后面添加. 我们在后面添加
$item-avatar-border-radius: 0;
可以发现头像变成方的了, 那怎么知道修改这个变量呢?
打开www/lib/ionic/scss/目录, 可以看到很多scss文件
├── _action-sheet.scss
├── _animations.scss
├── _backdrop.scss
├── _badge.scss
├── _bar.scss
├── _button-bar.scss
├── _button.scss
├── _checkbox.scss
├── _form.scss
├── _grid.scss
├── ionicons
├── ionic.scss
├── _items.scss
├── _list.scss
├── _loading.scss
├── _menu.scss
├── _mixins.scss
├── _modal.scss
...
这些都是官方的样式文件, 找到items.scss文件, 这个就是ion-item相关的样式, 再搜border-radius很快就能找到啦
具体的细节我就不说啦, 其它的修改都类似, 可以参考我的代码
popup的使用
关于$ionicPopup的详细使用, 可以参考官网
首先在controllers.js文件中添加一个controller:
.controller('messageCtrl', function($scope, $state, $ionicPopup, localStorageService, messageService) {
$scope.popup = {
isPopup: false,
index: 0
};
$scope.onSwipeLeft = function() {
$state.go("tab.friends");
};
$scope.popupMessageOpthins = function($index) {
$scope.popup.index = $index;
//这里通过$ionicPopup.show()方法创建了一个自定义的popup
$scope.popup.optionsPopup = $ionicPopup.show({
templateUrl: "templates/popup.html",
scope: $scope,
});
$scope.popup.isPopup = true;
};
//实现标为已读/未读, 注意$scope.popup.optionsPopup.close()方法
//用来关闭弹窗, 我竟然找了很久才发现这个接口
$scope.markMessage = function() {
var index = $scope.popup.index;
var message = $scope.messages[index];
if (message.showHints) {
message.showHints = false;
message.noReadMessages = 0;
}else{
message.showHints = true;
message.noReadMessages = 1;
}
$scope.popup.optionsPopup.close();
$scope.popup.isPopup = false;
messageService.updateMessage(message);
};
这里要注意两点
- 要在routes.js中将该controll传进去
- 需要通过自定义样式, 去掉自带的标题和按钮
//routes.js
.state('tab.message', {
url: '/message',
views: {
'tab-message': {
templateUrl: 'templates/tab-message.html',
controller: "messageCtrl"
}
}
})
自定义指令
细心的人会发现两个问题:
- 弹出popup时, 联系人列表没有动画效果
- 弹出popup后, 点击popup以外的地方, popup不能消失, 这两个问题, 就通过自定义指令来解决
首先在directives.js文件中添加rjCloseBackDrop指令, 用来解决上面第二个问题
.directive('rjCloseBackDrop', [function() {
return {
scope: false,//共享父scope
restrict: 'A',
replace: false,
link: function(scope, iElm, iAttrs, controller) {
//要在html上添加点击事件, 试了很久- -!
var htmlEl = angular.element(document.querySelector('html'));
htmlEl.on("click", function(event) {
if (event.target.nodeName === "HTML" &&
scope.popup.optionsPopup &&
scope.popup.isPopup) {
scope.popup.optionsPopup.close();
scope.popup.isPopup = false;
}
});
}
};
}])
再创建rjHoldActive指令, 用来解决第一个问题
.directive('rjHoldActive', ['$ionicGesture', '$timeout',
function($ionicGesture, $timeout, $ionicBackdrop) {
return {
scope: false,
restrict: 'A',
replace: false,
link: function(scope, iElm, iAttrs, controller) {
$ionicGesture.on("hold", function() {
iElm.addClass('active');
//300ms后恢复
$timeout(function() {
iElm.removeClass('active');
}, 300);
}, iElm);
}
};
}
])
最后分别在ion-list和ion-item上添加指令
<ion-list rj-close-back-drop>
<ion-item class="item-avatar"rj-hold-active ng-repeat="message in messages">
ok, 问题解决, 有点小激动~

自定义服务
前面讲的都是界面的东西, 那聊天记录的数据哪里来?
这里我们自定义一个假json数据, 用来模拟, 在www目录下创建文件data/json/messages.json
"messages": [{
"id": 0,
"name": "李明",
"pic": "img/adam.jpg",
"lastMessage": {
"time": "2015-10-12 15:34:55",
"content": "你在干什么?",
"isFromeMe": false
},
"noReadMessages": 2,
"showHints": true
},...
目前用到的数据都定义在这, 后面还需要什么数据再添加
我们把数据存到localstorage中, 大家都知道localstorage是基于key和value存储的
总不能把所以人的消息都存在一条key中, 所以我定义两个服务
- 把整个json数据拆成单独的message, 把独立的message合并成一个对象
- 封装setItem, 基本数据的存储获取
具体我就不贴代码了, 讲下服务定义好了, 怎么使用, 比如定义了一个test服务:
.factory('test', ['', function(){
return{
dosomething: function(){
return 0;
}
};
}])
用的时候直接把test注入, test.dosomething()调用:
.controller('someCtrl', function($scope, test) {
test.dosomething();
...
}
是不是很简单?
最后
这篇写的很长, 其实实现的功能很简单, 主要是要学会如何定义样式, 自定义指令, 自定义服务
这样在后面实现更复杂的功能时, 不至于纠结这些细节.
我发现一个人自学, 确实有些困难, 一些小问题百度根本搜不到, google上才比较靠谱
所以小伙伴们遇到困难, 不妨google一下, 基本都有答案的哦
有问题欢迎大家评论, 我会的会及时回复~
Ionic-wechat项目边开发边学(三):自定义样式,指令,服务的更多相关文章
- Ionic-wechat项目边开发边学(二):目录结构,header标签与路由
之前一直跟Linux驱动打交道,上层应用几乎为零,业余时间也不是很多,所以博客也不会写的非常详细,大家有问题尽管评论哦, 我有空会及时回复! 摘要 上一篇文章主要介绍了ionic的开发环境配置, 以及 ...
- Ionic-wechat项目边开发边学(一):环境搭建和创建一个项目
之前学AngularJS,教程过了一遍觉得很简单,但真正写几个Demo就错误百出,一个小小的功能要折腾很久.所以这次学Ionic,准备以开发一个项目为切入点去学,那么问题来了,开发什么项目呢? 纠结了 ...
- Ionic-wechat项目边开发边学(四):可伸缩输入框,下拉刷新, 置顶删除
摘要 上一篇文章主要介绍了ion-list的使用, ion-popup的使用, 通过sass自定义样式, localStorage的使用, 自定义指令和服务. 这篇文章实现的功能有消息的置顶与删除, ...
- Ios 项目从头开发 MVVM模式(三)
1.话说,本来想做个聚合查询功能.可是我的重点想研究xmpp聊天功能.所以使用mvvm模式做了全然模式51job主界面的页面. 2.首先给大家看我执行起来的界面. 3.界面非常easy,做这个界面主要 ...
- angular+ionic前后端分离开发项目中的使用
Ionic基于AngularJS构建而成,所以学习一些AngularJS的知识很有必要.Ionic并没有独立开发一套完整的Web应用框架,而是对AngularJS进行了扩展,给它添加了大量界面组件和其 ...
- [ionic开源项目教程] - 手把手教你使用移动跨平台开发框架Ionic开发一个新闻阅读APP
前言 这是一个系列文章,从环境搭建开始讲解,包括网络数据请求,将持续更新到项目完结.实战开发中遇到的各种问题的解决方案,也都将毫无保留的分享给大家. 关注订阅号:TongeBlog ,查看移动端跨平台 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- WeChat小程序开发-初学者笔记(一)
WeChat小程序开发学习第一天: 完成学习目标: 1.安装并了解Wechat小程序的基本环境, 2.可以利用已学知识的结合简单实现helloWorld界面. 学习过程: 1.首先在微信平台上进行相关 ...
- 项目游戏开发日记 No.0x000003
14软二杨近星(2014551622) 刚刚过去清明节, 意味着离交项目的时间, 还有三个星期, 有点着急了, 可是, 还是觉得无所适从... 项目进展: 刚刚过去的一周, 事非常多, 以至于, 进展 ...
随机推荐
- java synchronized 用法
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...
- css常见水平居中
行内元素居中 常见行内元素如文本,图片等居中时,通常是给父元素设置text-align:center 来实现.例如 HTML: <body> <div>我是文字,我要居中显示& ...
- 增强学习Reinforcement Learning经典算法梳理3:TD方法
转自:http://blog.csdn.net/songrotek/article/details/51382759 博客地址:http://blog.csdn.net/songrotek/artic ...
- 【Android】完善Android学习(六:API 4.0)
备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...
- 省队集训 Day3 吴清华
[题目大意] 给网格图,共有$n * n$个关键节点,横向.纵向距离均为$d$,那么网格总长度和宽度均为$(n+1) * d + 1$,最外围一圈除了四角是终止节点.要求每个关键节点都要通过线连向终止 ...
- max_element和min_element的用法
首先,max_element和min_elemetn看字面意思是求最大值和最小值,这个确实是这个意思.不过,需要注意的是,他返回的是最大值(最小值)的地址,而非最大值(最小值).对于一般数组的用法则是 ...
- bzoj 2440 容斥原理
首先根据样例或者自己打表大概可以知道,对于询问k,答案不会超过k<<1,那么我们就可以二分答案,求当前二分的值内有多少个数不是完全平方数的倍数,这样就可以了,对于每个二分到的值x,其中完全 ...
- js按值及引用传递中遇到的小问题
有人闲的蛋疼,非要在函数中使用如下方式传值,尼玛一下把我搞糊涂了.于是决定发挥打破沙锅问到底的精神搞清楚它. var a = 1,b = [], c = {}; function f(a, b, c) ...
- 双内网渗透代理之reGeorg+Proxifier
由于这个工具第一次体验感觉还不错,很稳定.因此在这记录一下reGeorg+Proxifier的配置及其使用. 下载地址 :https://github.com/sensepost/reGeorg.gi ...
- linux irq 自动探测
前言 编写驱动的时候,经常会用到中断,这时候我们在驱动初始化时就得申请中断,那么问题来了,中断号是多少呢?以前的中断号在板级相关的头文件里面已经静态定义好了,bsp的代码在内核启动过程也会根据那个帮我 ...