作者归档:shane

mysql复制DATA文件夹到新服务器后无法启动:“The server quit without updating PID file”

1.目录权限问题
对mysql的安装目录和数据目录分别进行授权

# chown -R mysql.mysql /usr/local/mysql
# chown -R mysql.mysql /data/mysql
# service mysqld start

2.可能进程里已经存在mysql进程
解决方法:用命令“ps -ef|grep mysqld”查看是否有mysqld进程,如果有使用“kill -9 进程号”杀死,然后重新启动mysqld!

3.可能是第二次在机器上安装mysql,有残余数据影响了服务的启动。
解决方法:去mysql的数据目录/data看看,如果存在mysql-bin.index,就赶快把它删除掉吧,它就是罪魁祸首了。

4.mysql在启动时没有指定配置文件时会使用/etc/my.cnf配置文件,请打开这个文件查看在[mysqld]节下有没有指定数据目录(datadir)。
解决方法:请在[mysqld]下设置这一行:datadir = /usr/local/mysql/data

5.可能是/usr/local/mysql/data/mysql.pid文件没有写的权限
解决方法 :给予权限,执行 “chown -R mysql:mysql /var/data” “chmod -R 755 /usr/local/mysql/data” 然后重新启动mysqld!

6.selinux惹的祸,如果是centos系统,默认会开启selinux
解决方法:关闭它,打开/etc/selinux/config,把SELINUX=enforcing改为SELINUX=disabled后存盘退出重启机器试试

7.删除mysql库文件/data/mysql/中的“ib_”文件,注意:* 执行该操作之前一定要对数据库进行备份,因为ibdata1存放的是所有数据文件,如果不小心删了库,那就惨了!!!(传说中的从删库到跑路。。。),然后重启mysql。

8.查看日志有如下错误提示:Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed。
解决办法:

# rm -rf ib_logfile*

然后启动mysql,问题解决!

9.看日志有这样的字样“initialize buffer pool,size=128.0M”,“cannot allocate memory for the pool”,大概意思是说无法分配足够的内存供pool使用。此时想到mysql配置文件中有相关的配置,于是更改如下参数:
innodb_buffer_pool_size = 128

配置文件中该值默认为128M

将这个值调小,再次启动mysql服务,问题解决!

10.系统上缺少mysql的依赖文件

# yum -y install libaio 
# yum -y install numactl

重新启动mysql服务,问题解决。

原文链接:https://blog.csdn.net/weixin_42272246/article/details/125534149

EditPlus、Notepad++、UltraEdit、EmEditor、LiteEdit、Sublime Text列选择方法

在使用富文本编辑器的时候,通常模式是行选择状态,由于今天想使用EditPlus列选择状态,
于是通过在网上收集的资料,总结出相关富文本编辑器的列选择的方法。

EditPlus
1)菜单:编辑 -> 选择 -> 列选择(Edit->Select->Column Select)
2)先按下 Alt + C ,释放,然后移动鼠标或键盘上下左右键进行列模块的移动
注意:在自动换行的模式下是不行的,改为不自动换行就行了。

Notepad++

1)按住 Alt 键,然后用鼠标进行选择
2)按住 Alt + Shift 键,然后用箭头(键盘的上下左右箭头)进行选择

UltraEdit

1)菜单栏有一个列块乒乓开关图标,选中它然后就进入列/块选择模式
2)按一下 Alt + C ,然后用鼠标或键盘进行选择

EmEditor

需要按住 Alt + C ,然后同时用鼠标进行选择

LiteEdit

1)按住ALT键然后用鼠标进行列块选择

2)点击菜单上的”列块选择”后用鼠标进行列块选择

Sublime Text

使用鼠标
每个平台使用不同的鼠标按钮:
OS X: 鼠标左键+⌥ OR: 鼠标中键; 新增选择: ⌘, 取消选择: ⇧+⌘;
WINDOWS: 鼠标右键+Shift OR: 鼠标中键 ; 新增选择:Ctrl, 取消选择: Alt
LINUX: 鼠标右键+Shift; 新增选择: Ctrl,取消选择: Alt;
使用键盘
OS X : Ctrl+Shift+⬆ , Ctrl+Shift+⬇ ;
WINDOWS: Ctrl+Alt+⬆, Ctrl+Alt+⬇ ;
LINUX: Ctrl+Alt+⬆, Ctrl+Alt+⬇ ;

文章来源:https://www.cnblogs.com/jpfss/p/9238456.html

FireFox设置打开收藏夹网页覆盖当前标签页的方法

FireFox设置打开收藏夹网页覆盖当前标签页的方法:

1、地址栏输入:about:config

2、输入browser.tabs.loadBookmarksInTabs,双击显示的值更改为false;

原文: https://www.cnblogs.com/tangguo123/p/9902219.html

附:关闭文件下载完成后自动扫描

输入browser.safebrowsing.downloads,将browser.safebrowsing.downloads.enabled值改成false。

angularjs学习总结 详细教程

转载,原作者未知

转自: https://www.cnblogs.com/stephenykk/p/3817063.html

1.AngularJS简单介绍

AngularJS 重新定义了前端应用的开发方式。面对HTML和JavaScript之间的界线,它非但不畏缩不前,反而正面出击,提出了有效的解决方案。
很多前端应用的开发框架,比如Backbone、EmberJS等,都要求开发者继承此框架特有的一些JavaScript对象。这种方式有其长处,但它不必要地污染了开发者自己代码的对象空间,还要求开发者去了解内存里那些抽象对象。尽管如此我们还是接受了这种方式,因为网络最初的设计无法提供 我们今天所需的交互性,于是我们需要框架,来帮我们填补JavaScript和HTML之间的鸿沟。而且有了它,你不用再“直接”操控DOM,只要给你的DOM注上metadata(即AngularJS里的directive们),然后让AngularJS来帮你操纵DOM。同时,AngularJS不依赖(也不妨碍)任何其他的框架。你甚至可以基于其它的框架来开发AngularJS应用。

API地址:http://docs.angularjs.org/api/;
AngularJS在github上的中文粗译版地址:https://github.com/basestyle/angularjs-cn。

什么时候该用AngularJS
AngularJS是一个 MV* 框架,最适于开发客户端的单页面应用。它不是个功能库,而是用来开发动态网页的框架。它专注于扩展HTML的功能,提供动态数据绑定(data binding),而且它能跟其它框架(如jQuery)合作融洽。
如果你要开发的是单页应用,AngularJS就是你的上上之选。Gmail、Google Docs、Twitter和Facebook这样的应用,都很能发挥AngularJS的长处。但是像游戏开发之类对DOM进行大量操纵、又或者单纯需要 极高运行速度的应用,就不是AngularJS的用武之地了。

2.功能和特性

2.1 特性一:双向的数据绑定

数据绑定可能是AngularJS最酷最实用的特性。它能够帮助你避免书写大量的初始代码从而节约开发时间。一个典型的web应用可能包含了80%的代码用来处理,查询和监听DOM。数据绑定是的代码更少,你可以专注于你的应用。
我们想象一下Model是你的应用中的简单事实。你的Model是你用来读取或者更新的部分。数据绑定指令提供了你的Model投射到view的方法。这些投射可以无缝的,毫不影响的应用到web应用中。
传统来说,当model变化了。 开发人员需要手动处理DOM元素并且将属性反映到这些变化中。这个一个双向的过程。一方面,model变化驱动了DOM中元素变化,另一方面,DOM元素的变化也会影响到Model。这个在用户互动中更加复杂,因为开发人员需要处理和解析
这些互动,然后融合到一个model中,并且更新View。这是一个手动的复杂过程,当一个应用非常庞大的时候,将会是一件非常费劲的事情。
这里肯定有更好的解决方案!那就是AngularJS的双向数据绑定,能够同步DOM和Model等等。

2.2 特性二:模板

在AngularJS中,一个模板就是一个HTML文件。但是HTML的内容扩展了,包含了很多帮助你映射model到view的内容。
HTML模板将会被浏览器解析到DOM中。DOM然后成为AngularJS编译器的输入。AngularJS将会遍历DOM模板来生成一些指导,即,directive(指令)。所有的指令都负责针对view来设置数据绑定。
我们要理解AuguarJS并不把模板当做String来操作。输入AngularJS的是DOM而非string。数据绑定是DOM变化,不是字符串的连接或者innerHTML变化。使用DOM作为输入,而不是字符串,是AngularJS区别于其它的框架的最大原因。使用DOM允许你扩展指令词汇并且可以创建你自己的指令,甚至开发可重用的组件。
最大的好处是为设计师和开发者创建了一个紧密的工作流。设计师可以像往常一样开发标签,然后开发者拿过来添加上功能,通过数据绑定将会使得这个过程非常简单。
这里有一个例子,我们使用ng-repeat指令来循环图片数组并且加入img模板,如下:

<script type="text/javascript">
    AlbumCtrl($scope) {
        scope.images = [{
            "thumbnail": "img/image_01.png",
            "description": "Image 01 description"
        }, {
            "thumbnail": "img/image_02.png",
            "description": "Image 02 description"
        }, {
            "thumbnail": "img/image_03.png",
            "description": "Image 03 description"
        }];
    }
</script>
<div ng-controller="AlbumCtrl">
    <ul>
        <li ng-repeat="image in images">
            <img ng-src="http://m.cnblogs.com/142260/{{image.thumbnail}}" rel="nofollow" />
        </li>
    </ul>
</div>

这里还有一件事值得提一句,AngularJS并不强制你学习一个新的语法或者从你的应用中提出你的模板。

2.3 特性三:MVC

针对客户端应用开发AngularJS吸收了传统的MVC基本原则。MVC或者Model-View-Controll设计模式针对不同的人可能意味不同的东西。AngularJS并不执行传统意义上的MVC,更接近于MVVM(Moodel-View-ViewModel)。
Model
model是应用中的简单数据。一般是简单的javascript对象。这里没有必要继承框架的classes,使用proxy对象封装或者使用特别的setter/getter方法来访问。事实上我们处理vanilla javascript的方法就是一个非常好的特性,这种方法使得我们更少使用应用的原型。
ViewModel
viewmodel是一个用来提供特别数据和方法从而维护指定view的对象。
viewmodel是$scope的对象,只存在于AnguarJS的应用中。$scope只是一个简单的js对象,这个对象使用简单的API来侦测和广播状态变化。
Controller
controller负责设置初始状态和参数化$scope方法用以控制行为。需要指出的controller并不保存状态也不和远程服务互动。
View
view是AngularJS解析后渲染和绑定后生成的HTML 。这个部分帮助你创建web应用的架构。$scope拥有一个针对数据的参考,controller定义行为,view处理布局和互动。

2.4 特性四:服务和依赖注入

AngularJS服务其作用就是对外提供某个特定的功能。
AngularJS拥有内建的依赖注入(DI)子系统,可以帮助开发人员更容易的开发,理解和测试应用。
DI允许你请求你的依赖,而不是自己找寻它们。比如,我们需要一个东西,DI负责找创建并且提供给我们。
为了而得到核心的AngularJS服务,只需要添加一个简单服务作为参数,AngularJS会侦测并且提供给你:

function EditCtrl($scope, $location, $routeParams) {
    // Something clever here...
}

你也可以定义自己的服务并且让它们注入:

angular.module('MyServiceModule', []).
factory('notify', ['$window', function(win) {
    return function(msg) {
        win.alert(msg);
    };
}]);

function myController(scope, notifyService) {
    scope.callNotify = function(msg) {
        notifyService(msg);
    };
}
myController.$inject = ['$scope', 'notify'];

2.5 特性五:指令(Directives)

指令是我个人最喜欢的特性。你是不是也希望浏览器可以做点儿有意思的事情?那么AngularJS可以做到。
指令可以用来创建自定义的标签。它们可以用来装饰元素或者操作DOM属性。可以作为标签、属性、注释和类名使用。
这里是一个例子,它监听一个事件并且针对的更新它的$scope ,如下:

myModule.directive('myComponent', function(mySharedService) {
    return {
        restrict: 'E',
        controller: function($scope, $attrs, mySharedService) {
            $scope.$on('handleBroadcast', function() {
                $scope.message = 'Directive: ' + mySharedService.message;
            });
        },
        replace: true,
        template: '<input>'
    };
});

然后,你可以使用这个自定义的directive来使用:

<my-component ng-model="message"></my-component>

使用一系列的组件来创建你自己的应用将会让你更方便的添加,删除和更新功能。

3. 功能 – 数据绑定

AngularJS的双向数据绑定,意味着你可以在Mode(JS)中改变数据,而这些变动立刻就会自动出现在View上,反之亦然。即:一方面可以做到model变化驱动了DOM中元素变化,另一方面也可以做到DOM元素的变化也会影响到Model。
在我们使用jQuery的时候,代码中会大量充斥类似这样的语句:var val = $(‘#id’).val(); $(‘#id’).html(str);等等,即频繁的DOM操作(读取和写入),其实我们的最终目的并不是要操作DOM,而是要实现业务逻辑。ng的绑定将让你摆脱DOM操作,只要模板与数据通过声明进行了绑定,两者将随时保持同步,最新的数据会实时显示在页面中,页面中用户修改的数据也会实时被记录在数据模型中。
从View到Controller再到View的数据交互(例01):

<html ng-app="demoApp">
……
<input type="text" ng-model="user.name" placeholder="请输入名称"/>
Hello, {{ user.name }}!
……

关键: ng-app 、 ng-model 和 { {user.name } }
首先: 元素的ng-app属性。标识这个DOM里面的内容将启用AngularJS应用。
其次:告诉AngularJS,对页面上的“user.name” 这个Model进行双向数据绑定。
第三:告诉AngularJS,在“{{ user.name}}”这个指令模版上显示“user.name”这个Model的数据。
从Server到Controller再到View的数据交互(例02):

<html ng-app="demoApp">
……
<div ng-controller="demoController">
<input type="text" ng-model="user.name" disabled="disabled"/>
<a href="javascript:void(0);" target="_blank" rel="nofollow">获取名字</a>
……
demoApp.controller("demoController", function($http, $scope) {
    $scope.getAjaxUser = function() {
        // $http.get({url:"../xxx.action"}).success(function(data){
        // $scope.user= data;
        // });
        $scope.user = {
            "name": "从JOSN中获取的名称",
            "age": 22
        };
    };
});

改变$scope中的user,View也会自动更新。

4. scopes、module、controller 之 scopes

$scope是一个把view(一个DOM元素)连结到controller上的对象。在我们的MVC结构里,这个 $scope 将成为model,它提供一个绑定到DOM元素(以及其子元素)上的excecution context。
尽管听起来有点复杂,但 $scope 实际上就是一个JavaScript对象,controller和view都可以访问它,所以我们可以利用它在两者间传递信息。在这个 $scope 对象里,我们既存储数据,又存储将要运行在view上的函数。
每一个Angular应用都会有一个 $rootScope。这个 $rootScope 是最顶级的scope,它对应着含有 ng-app 指令属性的那个DOM元素。
app.run(function($rootScope) { $rootScope.name = “张三”; });
如果页面上没有明确设定 $scope ,Angular 就会把数据和函数都绑定到这里, 第一部分中的例子就是靠这一点成功运行的。
这样,我们就可以在view的任何地方访问这个name属性,使用模版表达式{{}},像这样:
{{ name }}

5 . scopes、module、controller 之 module

首先需要明确一下模板的概念。在我还不知道有模板这个东西的时候,曾经用js拼接出很长的HTML字符串,然后append到页面中,这种方式想想真是又土又笨。后来又看到可以把HTML代码包裹在一个<script>标签中当作模板,然后按需要取来使用。
在ng中,模板十分简单,它就是我们页面上的HTML代码,不需要附加任何额外的东西。在模板中可以使用各种指令来增强它的功能,这些指令可以让你把模板和数据巧妙的绑定起来。
在<html>标签上多了一个属性ng-app=”MyApp”,它的作用就是用来指定ng的作用域是在<html>标签以内部分。在js中,我们调用angular对象的module方法来声明一个模块,模块的名字和ng-app的值对应。这样声明一下就可以让ng运行起来了。
示例:

<html ng-app="demoApp">
var demoApp = angular.module('demoApp', []);

6 . scopes、module、controller 之 controller

要明确创建一个$scope 对象,我们就要给DOM元素安上一个controller对象,使用的是ng-controller 指令属性:

<div ng-controller="MyController"> {{ person.name }} </div>

ng-controller指令给所在的DOM元素创建了一个新的$scope 对象,并将这个$scope 对象包含进外层DOM元素的$scope 对象里。在上面的例子里,这个外层DOM元素的$scope 对象,就是$rootScope 对象。这个scope链是这样的:

所有scope都遵循原型继承(prototypal inheritance),这意味着它们都能访问父scope们。对任何属性和方法,如果AngularJS在当前scope上找不到,就会到父 scope上去找,如果在父scope上也没找到,就会继续向上回溯,一直到$rootScope 上。即如果controller是多层嵌套的,就会从最里面一直往外找,这个scope链是这样的:

唯一的例外:有些指令属性可以选择性地创建一个独立的scope,让这个scope不继承它的父scope们,这个会在指令详解中说明。

7. ajax

$http 服务是AngularJS的核心服务之一,它帮助我们通过XMLHttpRequest对象或JSONP与远程HTTP服务进行交流。
$http 服务是这样一个函数:它接受一个设置对象,其中指定了如何创建HTTP请求;它将返回一个承诺(*参考JavaScript异步编程的promise模式),其中提供两个方法: success方法和error方法。

demoApp.controller("demoController", function($http, $scope) {
    $scope.getAjaxUser = function() {
        $http.get({
            url: "../xxx.action"
        }).success(function(data) {
            alert(data);
        }).error(function() {
            Alert(“出错了!”);
        });

    };
});

AngularJS的AJAX与jquery等框架的AJAX基本一致,这里就不多说了。

8. 表达式

ng中的表达式与javascript表达式类似但是不可以划等号,它是ng自己定义的一套模式。表达式可以作为指令的值,如ng-modle=”people.name”、ng-click=”showMe()”,看起来是如此像字符串,故而也叫字符串表达式。也可以在标记中使用表达式,如{{1+2}},或者与过滤器一起使用{{1+2 | currency}}。在框架内部,字符串不会简单的使用eval()来执行,而是有一个专门的$parse服务来处理。在ng表达式中不可以使用循环语句、判断语句,事实上在模板中使用复杂的表达式也是一个不推荐的做法,这样视图与逻辑就混杂在一起了
我们在使用其他模板库时,一般都会有模板的循环输出、分支输出、逻辑判断等类似的控制。
要想理解指令属性的运作,我们必须先理解表达式。在之前的例子里我们已经见过表达式,例如 {{ user.name }}。

{{ 8 + 1 }} 9
{{ person }} {"name":"Ari Lerner"}
{{ 10 * 3.3 | currency }} $33.00

表达式粗略来看有点像 eval(javascript) 的结果。它们会经过Angular.js的处理,从而拥有以下重要而独特的性质:

  • 所有表达式都在scope这个context里被执行,因此可以使用所有本地 $scope 中的变量。
  • 如果一个表达式的执行导致类型错误或引用错误,这些错误将不会被抛出。
  • 表达式里不允许任何控制函数流程的功能(如if/else等条件语句)
  • 表达式可接受一个或多个串联起来的过滤器。

9. 过滤器

过滤器(filter)正如其名,作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果。主要用在数据的格式化上,例如获取一个数组中的子集,对数组中的元素进行排序等。过滤器通常是伴随标记来使用的,将你model中的数据格式化为需要的格式。表单的控制功能主要涉及到数据验证以及表单控件的增强。ng内置了一些过滤器,它们是:
currency(货币)、date(日期)、filter(子串匹配)、json(格式化json对象)、limitTo(限制个数)、lowercase(小写)、uppercase(大写)、number(数字)、orderBy(排序)。

过滤器使用方式

总共九种。除此之外还可以自定义过滤器,这个就强大了,可以满足任何要求的数据处理。Filter还是很简单的,需要明白的是内置的filter如何使用,以及自己如何定义一个filter。
filter的两种使用方法:

9.1 在模板中使用filter
我们可以直接在{{}}中使用filter,跟在表达式后面用 | 分割,语法如下:

{{ expression | filter }}

也可以多个filter连用,上一个filter的输出将作为下一个filter的输入:

{{ expression | filter1 | filter2 | … }}

filter可以接收参数,参数用 : 进行分割,如下:

{{ expression | filter:argument1:argument2:… }}

除了对{{}}中的数据进行格式化,我们还可以在指令中使用filter,例如先对数组array进行过滤处理,然后再循环输出:

<span ng-repeat="a in array | filter ">

9.2 在controller和service中使用filter
我们的js代码中也可以使用过滤器,方式就是我们熟悉的依赖注入,例如我要在controller中使用currency过滤器,只需将它注入到该controller中即可,代码如下:

app.controller('testC',function($scope,currencyFilter){
    $scope.num = currencyFilter(123534);
}

在模板中使用{{num}}就可以直接输出$123,534.00了!在服务中使用filter也是同样的道理。
如果你要在controller中使用多个filter,并不需要一个一个注入吗,ng提供了一个$filter服务可以来调用所需的filter,你只需注入一个$filter就够了,使用方法如下:

app.controller('testC', function($scope, $filter) {
    $scope.num = $filter('currency')(123534);
    $scope.date = $filter('date')(new Date());
})

可以达到同样的效果。好处是你可以方便使用不同的filter了。

9.3 ng的内置过滤器

ng内置了九种过滤器,使用方法都非常简单,看文档即懂。不过为了以后不去翻它的文档,我在这里还是做一个详细的记录。
currency(货币)、date(日期)、filter(子串匹配)、json(格式化json对象)、limitTo(限制个数)、lowercase(小写)、uppercase(大写)、number(数字)、orderBy(排序)

9.3.1 currency (货币处理)
使用currency可以将数字格式化为货币,默认是美元符号,你可以自己传入所需的符号,例如我传入人民币:

{{num | currency : '¥'}}

9.3.2 date (日期格式化)
原生的js对日期的格式化能力有限,ng提供的date过滤器基本可以满足一般的格式化要求。用法如下:

{{date | date : 'yyyy-MM-dd hh:mm:ss EEEE'}}

参数用来指定所要的格式,y M d h m s E 分别表示 年 月 日 时 分 秒 星期,你可以自由组合它们。也可以使用不同的个数来限制格式化的位数。另外参数也可以使用特定的描述性字符串,例如“shortTime”将会把时间格式为12:05 pm这样的。ng提供了八种描述性的字符串,个人觉得这些有点多余,我完全可以根据自己的意愿组合出想要的格式,不愿意去记这么多单词~

9.3.3 filter(匹配子串)
这个名叫filter的filter。用来处理一个数组,然后可以过滤出含有某个子串的元素,作为一个子数组来返回。可以是字符串数组,也可以是对象数组。如果是对象数组,可以匹配属性的值。它接收一个参数,用来定义子串的匹配规则。下面举个例子说明一下参数的用法,我用现在特别火的几个孩子定义了一个数组:

$scope.childrenArray = [
    { name: 'kimi', age: 3 },
    { name: 'cindy', age: 4 },
    { name: 'anglar', age: 4 },
    { name: 'shitou', age: 6 },
    { name: 'tiantian', age: 5 }
];
$scope.func = function(e){return e.age>4;}{{ childrenArray | filter : 'a' }} //匹配属性值中含有a的
{{ childrenArray | filter : 4 }} //匹配属性值中含有4的
{{ childrenArray | filter : {name : 'i'} }} //参数是对象,匹配name属性中含有i的
{{childrenArray | filter : func }} //参数是函数,指定返回age>4的

9.3.4 json(格式化json对象)
json过滤器可以把一个js对象格式化为json字符串,没有参数。这东西有什么用呢,我一般也不会在页面上输出一个json串啊,官网说它可以用来进行调试,嗯,是个不错的选择。或者,也可以用在js中使用,作用就和我们熟悉的JSON.stringify()一样。用法超级简单:

{{ jsonTest | json}}

9.3.5 limitTo(限制数组长度或字符串长度)
limitTo过滤器用来截取数组或字符串,接收一个参数用来指定截取的长度,如果参数是负值,则从数组尾部开始截取。个人觉得这个filter有点鸡肋,首先只能从数组或字符串的开头/尾部进行截取,其次,js原生的函数就可以代替它了,看看怎么用吧:

{{ childrenArray | limitTo : 2 }} //将会显示数组中的前两项

9.3.6 lowercase(小写)
把数据转化为全部小写。太简单了,不多解释。同样是很鸡肋的一个filter,没有参数,只能把整个字符串变为小写,不能指定字母。怎么用我都懒得写了。uppercase(大写)
同上。

9.3.7 number(格式化数字)
number过滤器可以为一个数字加上千位分割,像这样,123,456,789。同时接收一个参数,可以指定float类型保留几位小数:

{{ num | number : 2 }}

9.3.8 orderBy(排序)
orderBy过滤器可以将一个数组中的元素进行排序,接收一个参数来指定排序规则,参数可以是一个字符串,表示以该属性名称进行排序。可以是一个函数,定义排序属性。还可以是一个数组,表示依次按数组中的属性值进行排序(若按第一项比较的值相等,再按第二项比较),还是拿上面的孩子数组举例:

<div>{{ childrenArray | orderBy : 'age' }}</div> //按age属性值进行排序,若是-age,则倒序
<div>{{ childrenArray | orderBy : orderFunc }}</div> //按照函数的返回值进行排序
<div>{{ childrenArray | orderBy : ['age','name'] }}</div> //如果age相同,按照name进行排序

内置的过滤器介绍完了,写的我都快睡着了。。。正如你所看到的,ng内置的过滤器也并不是万能的,事实上好多都比较鸡肋。更个性化的需求就需要我们来定义自己的过滤器了,下面来看看如何自定义过滤器。

9.4 自定义过滤器及示例
filter的自定义方式也很简单,使用module的filter方法,返回一个函数,该函数接收
输入值,并返回处理后的结果。话不多说,我们来写一个看看。比如我需要一个过滤器,它可以返回一个数组中下标为奇数的元素,代码如下:

app.filter('odditems', function() {
    return function(inputArray) {
        var array = [];
        for (var i = 0; i < inputArray.length; i++) {
            if (i % 2 !== 0) {
                array.push(inputArray[i]);
            }
        }
        return array;
    }
});

格式就是这样,你的处理逻辑就写在内部的那个闭包函数中。你也可以让自己的过滤器接收参数,参数就定义在return的那个函数中,作为第二个参数,或者更多个参数也可以。
自定义过滤器实例(例04):

    /* View html */ 
First name:<input ng-model="user.firstName" /><br/> 
Last name:<input ng-model="user.lastName" /> <br/> 
First name:{{user.firstName}} Last name:{{user.lastName}} <br/> 
Fullname:{{user | flFullname}}<br/> 
Fullname:{{user | flFullname:"-"}}<br/> 
Fullname:{{user | flFullname:"•" | uppercase }}
    /* Controller js */
demoApp.filter("flFullname", function() {
    return function(user, sep) {
        sep = sep || " ";
        user = user || {};
        fullName = "";
        if (user.firstName) { fullName += user.firstName; }
        if (user.lastName) { fullName = fullName + sep + user.lastName; }
        if (fullName && fullName.length > 0) {
            return fullName;
        } else { return ""; }
    };
});

10. 指令(directive)
通过使用模板,我们可以把model和controller中的数据组装起来呈现给浏览器,还可以通过数据绑定,实时更新视图,让我们的页面变成动态的。
模板中可以使用的东西包括以下四种:
1.指令(directive):ng提供的或者自定义的标签和属性,用来增强HTML表现力;
2.标记(markup):即双大括号{{}},可将数据单向绑定到HTML中;
3.过滤器(filter):用来格式化输出数据;
4.表单控制:用来增强表单的验证功能。
其中,指令无疑是使用量最大的,ng内置了很多指令用来控制模板,如ng-repeat,ng-class,也有很多指令来帮你完成业务逻辑,如ng-controller,ng-model。
指令的几种使用方式如下:

  • 作为标签:<my-dir>
  • 作为属性:<span my-dir=”exp”></span>
  • 作为注释:<!– directive: my-dir exp –>
  • 作为类名:<span class=”my-dir: exp;”></span>

其实常用的就是作为标签和属性。

10.1 样式相关的指令
既然模板就是普通的HTML,那我首要关心的就是样式的控制,元素的定位、字体、背景色等等如何可以灵活控制。下面来看看常用的样式控制指令。

10.1.1 ng-class
ng-class用来给元素绑定类名,其表达式的返回值可以是以下三种:

  • 类名字符串,可以用空格分割多个类名,如’redtext boldtext’;
  • 类名数组,数组中的每一项都会层叠起来生效;
  • 一个名值对应的map,其键值为类名,值为boolean类型,当值为true时,该类会被加在元素上。

下面来看一个使用map的例子:
ng-class测试
红色 加粗 删除线

map:{redtext:{{red}}, boldtext:{{bold}}, striketext:{{strike}}}

如果你想拼接一个类名出来,可以使用插值表达式,如:

<div class=”{{style}}text”>字体样式测试</div>

然后在controller中指定style的值:

$scope.style = ‘red’;

注意我用了class而不是ng-class,这是不可以对换的,官方的文档也未做说明,姑且认为这是ng的语法规则吧。
与ng-class相近的,ng还提供了ng-class-odd、ng-class-even两个指令,用来配合ng-repeat分别在奇数列和偶数列使用对应的类。这个用来在表格中实现隔行换色再方便不过了。

10.1.2 ng-style
ng-style用来绑定元素的css样式,其表达式的返回值为一个js对象,键为css样式名,值为该样式对应的合法取值。用法比较简单:

<div ng-style="{color:'red'}">ng-style测试</div>
<div ng-style="style">ng-style测试</div>
$scope.style = {color:'red'};

10.1.3 ng-show,ng-hide
对于比较常用的元素显隐控制,ng也做了封装,ng-show和ng-hide的值为boolean类型的表达式,当值为true时,对应的show或hide生效。框架会用display:block和display:none来控制元素的显隐。

10.1.4 表单控件功能相关指令
对于常用的表单控件功能,ng也做了封装,方便灵活控制。
ng-checked控制radio和checkbox的选中状态
ng-selected控制下拉框的选中状态
ng-disabled控制失效状态
ng-multiple控制多选
ng-readonly控制只读状态
以上指令的取值均为boolean类型,当值为true时相关状态生效,道理比较简单就不多做解释。注意: 上面的这些只是单向绑定,即只是从数据到模板,不能反作用于数据。要双向绑定,还是要使用 ng-model 。

10.2 事件绑定相关指令
事件绑定是javascrpt中比较重要的一部分内容,ng对此也做了详细的封装,正如我们之前使用过的ng-click一样,事件的指令如下:
ng-click
ng-change
ng-dblclick
ng-mousedown
ng-mouseenter
ng-mouseleave
ng-mousemove
ng-mouseover
ng-mouseup
ng-submit
事件绑定指令的取值为函数,并且需要加上括号,例如:

<select ng-change=”change($event)”></select>

然后在controller中定义如下:

$scope.change = function($event){
    alert($event.target);
    //……………………
}

在模板中可以用变量$event将事件对象传递到controller中。
对于ng的这种设计,一些人有所质疑,视图与事件绑定混在一起到底好不好?我们不是要讲究视图与逻辑分离吗?如此一来,把事件的绑定又变回了内联的,岂不是历史的倒退。我也一样对此表示不解,因为不写onclick已经很多年。。。但既然已经存在了,我们不妨往合理的方向上想一想,或许ng的设计者压根就不想让模板成为单纯的视图层,本来就是想增强HTML,让它有一点业务能力。这么想的话似乎也能想通,好吧,先欺骗一下自己吧~

10.3 特殊的ng-src和ng-href
1) 浏览器加载静态HTML文件并解析为DOM;
2) 浏览器加载angular.js文件;
3) angular监听DOMContentLoaded 事件,监听到时开始启动;
4) angular寻找ng-app指令,确定作用范围;
5) 找到app中定义的Module使用$injector服务进行依赖注入;
6) 根据$injector服务创建$compile服务用于编译;
7) $compile服务编译DOM中的指令、过滤器等;
8) 使用ng-init指令,将作用域中的变量进行替换;
9) 最后生成了我们在最终视图。
可以看到,ng框架是在DOMcontent加载完毕后才开始发挥作用。假如我们模板中有一张图片如下:

<img src="http://m.cnblogs.com/142260/”{{imgUrl}}” />

那么在页面开始加载到ng编译完成之前,页面上会一直显示一张错误的图片,因为路径{{imgUrl}}还未被替换。
为了避免这种情况,我们使用ng-src指令,这样在路径被正确得到之前就不会显示找不到图片。同理,<a>标签的href属性也需要换成ng-href,这样页面上就不会先出现一个地址错误的链接。
顺着这个思路再多想一点,我们在模板中使用{{}}显示数据时,在ng编译完成之前页面上岂不是会显示出大括号及里面的表达式?确实是这样。为了避免这个,ng中有一个与{{}}等同的指令:ng-bind,同样用于单向绑定,在页面刚加载的时候就不会显示出对用户无用的数据了。尽管这样你可能不但没舒心反而更纠结了,{{}}那么好用易理解,还不能用了不成?好消息是我们依然可以使用。因为我编写的是单页面应用,页面只会在加载index.html的时
候出这个问题,只需在index.html中的模板中换成ng-bind就行。其他的模板是我们动态加载的,就可以放心使用{{}}了。

10.4 自定义指令示例
下面我们来解析下指令的例子(例07)。
首先,我们定义一个名为userInfo的指令:

demoApp.directive('userInfo', function() {
    return {
        restrict: 'E',
        templateUrl: 'userInfoTemplate.html',
        replace: true,
        transclude: true,
        scope: {
            mytitle: '=etitle'
        },
        link: function(scope, element, attrs) {
            scope.showText = false;
            scope.toggleText = function() {
                scope.showText = !scope.showText;
            }
        }
    };
})

Restrict为’E’:用作标签;replace为true:用模板替换当前标签;transclude为true:将当前元素的内容转移到模板中;scope 为 {mytitle : ‘=etitle’}:定义一个名为mytitle的MODEL,其值指向当前元素的etitle属性;templateUrl为’userInfoTemplate.html’:模板内容为ng-template定义ID为userInfoTemplate.html的内容;link:指定所包含的行为。userInfoTemplate.html模板为:

<script type="text/ng-template" id="userInfoTemplate.html">
    <div class="mybox">
        <div class="mytitle" style="cursor: pointer;" ng-click="toggleText()">
            { {mytitle} }
        </div>
        <div ng-transclude ng-show="showText">
        </div>
    </div>
</script>

将当前元素的内容添加到有ng-transclude属性的这个DIV下,默认是隐藏的。
Controller信息:

demoApp.controller("test7Controller", function($scope) {
    $scope.title = '个人简介';
    $scope.text = '大家好,我正在研究AngularJs,欢迎大家与我交流。';
    $scope.updateInfo = function() {
        $scope.title = '个人信息';
        $scope.text = '大家好,今天天气真好!';
    }
});

指令使用方式(View信息)为:

<user-info etitle="title">{ {text} }</user-info>

Etitle指向Controller中的$scope.title。注意命名方式:指令名为userInfo,对应的标签为user-info。

11. 服务(service)
服务这个概念其实并不陌生,在其他语言中如java便有这样的概念,其作用就是对外提供某个特定的功能,如消息服务,文件压缩服务等,是一个独立的模块。ng的服务是这样定义的:
Angular services are singletons objects or functions that carry out specific tasks common to web apps.
它是一个单例对象或函数,对外提供特定的功能。
首先是一个单例,即无论这个服务被注入到任何地方,对象始终只有一个实例。
其次这与我们自己定义一个function然后在其他地方调用不同,因为服务被定义在一个模块中,所以其使用范围是可以被我们管理的。ng的避免全局变量污染意识非常强。
ng提供了很多内置的服务,可以到API中查看http://docs.angularjs.org/api/。知道了概念,我们来拉一个service出来溜溜,看看到底是个什么用法。
我们在controller中直接声明$location服务,这依靠ng的依赖注入机制。$location提供地址栏相关的服务,我们在此只是简单的获取当前的地址。
服务的使用是如此简单,我们可以把服务注入到controller、指令或者是其他服务中。

11.1 自定义服务
如同指令一样,系统内置的服务以$开头,我们也可以自己定义一个服务。定义服务的方式有如下几种:

  • 使用系统内置的$provide服务;
  • 使用Module的factory方法;
  • 使用Module的service方法。

下面通过一个小例子来分别试验一下。我们定义一个名为remoteData服务,它可以从远程获取数据,这也是我们在程序中经常使用的功能。不过我这里没有远程服务器,就写死一点数据模拟一下。

//使用$provide来定义
var app = angular.module('MyApp', [], function($provide) {
    $provide.factory('remoteData', function() {
        var data = { name: 'n', value: 'v' };
        return data;
    });
});
//使用factory方法
app.factory('remoteData', function() {
    var data = { name: 'n', value: 'v' };
    return data;
});
//使用service方法
app.service('remoteData', function() {
    this.name = 'n';
    this.value = 'v';
});

Module的factory和$provide的factory方法是一模一样的,从官网文档看它们其实就是一回事。至于Module内部是如何调用的,我此处并不打算深究,我只要知道怎么用就好了。
再看Module的service方法,它没有return任何东西,是因为service方法本身返回一个构造器,系统会自动使用new关键字来创建出一个对象。所以我们看到在构造器函数内可以使用this,这样调用该服务的地方便可以直接通过remoteData.name来访问数据了。

11.2 管理服务的依赖关系
服务与服务中间可以有依赖关系,例如我们这里定义一个名为validate的服务,它的作用是验证数据是否合法,它需要依赖我们从远程获取数据的服务remoteData。代码如下:
在factory的参数中,我们可以直接传入服务remoteData,ng的依赖注入机制便帮我们做好了其他工作。不过一定要保证这个参数的名称与服务名称一致,ng是根据名称来识别的。若参数的名次与服务名称不一致,你就必须显示的声明一下,方式如下:

app.factory('validate', ['remoteData', function(remoteDataService) {
    return function() {
        if (remoteDataService.name == 'n') {
            alert('验证通过');
        }
    };
}]);

我们在controller中注入服务也是同样的道理,使用的名称需要与服务名称一致才可以正确注入。否则,你必须使用$inject来手动指定注入的服务。比如:

function testC(scope, rd) {
    scope.getData = function() {
        alert('name:' + rd.name + ' value:' + rd.value);
    }
}
testC.$inject = ['$scope', 'remoteData'];

在controller中注入服务,也可以在定义controller时使用数组作为第二个参数,在此处
把服务注入进去,这样在函数体中使用不一致的服务名称也是可以的,不过要确保注入的顺序是一致的,如:

app.controller('testC', ['$scope', 'remoteData', function($scope, rd) {
    $scope.getData = function() {
        alert('name:' + rd.name + ' value:' + rd.value);
    }
}]);

11.3 自定义服务示例
接下来让我们看下例子(例08 自定义服务)代码,自定义userService服务:

demoApp.factory('userService', ['$http', function($http) {
    var doGetUser = function(userId, path) {
        //return $http({
        //method: 'JSONP',
        //url: path
        //});
        /*手动指定数据*/
        var data = { userId: "woshishui", userName: "我是谁", userInfo: "我是谁!我是谁!" };;
        if (userId == 'zhangsan') {
            data = { userId: "zhangsan", userName: "张三", userInfo: "我是张三,我为自己" };
        } else if (userId == 'lisi') {
            data = { userId: "lisi", userName: "李四", userInfo: "我是李四,我为卿狂!" };
        }
        return data;
    }
    return {
        /*userService对外暴露的函数,可有多个*/
        getUser: function(userId) {
            return doGetUser(userId, '../xxx/xxx.action');
        }
    };
}]);

我们创建了一个只有一个方法的userService,getUser为这个服务从后台获取用户信息的函数,并且对外暴露。当然,由于这是一个静态的例子,无法访问后台,那么我们便制定其返回的数据。
然后我们把这个服务添加到我们的controller中。我们建立一个controller并加载(或者注入)userService作为运行时依赖,我们把service的名字作为参数传递给controller 函数:

demoApp.controller("test8Controller", function($scope, userService) {
    /*文章信息*/
    $scope.articles = [{
        title: "爱飞像风",
        userId: "zhangsan",
        userName: "张三"
    }, {
        title: "无法停止的雨",
        userId: "lisi",
        userName: "李四"
    }];
    $scope.showUserInfo = false; //显示作者详细信息开关
    $scope.currentUser = {}; //当前选中的作者
    $scope.getUserInfo = function(userId) {
        $scope.currentUser = userService.getUser(userId);
        //调用 userService的getUser函数
        $scope.showUserInfo = true;
        setTimeout(function() { //定时器:隐藏作者详细信息
            $scope.showUserInfo = false;
        }, 3000);
    }
});

我们的userService注入到我们的test8Controller后,我们就可以像使用其他服务(我们前面提到的$http服务)一样的使用userService了。
相关的HTML代码如下:

/* View HTML*/
<tr ng-repeat="article_ in articles">
    <td>
        {{article_.title}}
    </td>
    <td>
        <a href="javascript:void(0);" target="_blank" rel="nofollow">
    </td>
</tr>
......
<div ng-show="showUserInfo">
    用户ID:{{currentUser.userId}}<br/> 用户名:{{currentUser.userName}}
    <br/> 用户简介:{{currentUser.userInfo}}
    <br/>
</div>

12. 依赖注入DI
通过依赖注入,ng想要推崇一种声明式的开发方式,即当我们需要使用某一模块或服务时,不需要关心此模块内部如何实现,只需声明一下就可以使用了。在多处使用只需进行多次声明,大大提高可复用性。
比如我们的controller,在定义的时候用到一个$scope参数。

app.controller('testC',function($scope){});

如果我们在此处还需操作其他的东西,比如与浏览器地址栏进行交互。我们只需再多添一个参数$location进去:

app.controller('testC',function($scope,$location){});

这样便可以通过$location来与地址栏进行交互了,我们仅仅是声明了一下,所需的其他代码,框架已经帮我们注入了。我们很明显的感觉到了这个函数已经不是常规意义上的javascript函数了,在常规的函数中,把形参换一个名字照样可以运行,但在此处若是把$scope换成别的名字,程序便不能运行了。因为这是已经定义好的服务名称。
这便是依赖注入机制。顺理成章的推断,我们可以自己定义模块和服务,然后在需要的地方进行声明,由框架来替我们注入。
来看下我们如何定义一个服务:

app.factory('tpls',function(){
    return ['tpl1','tpl2','tpl3','tpl4'];
});

看上去相当简单,是因为我在这里仅仅是直接返回一个数组。在实际应用中,这里应该是需要向服务器发起一个请求,来获取到这些模板们。服务的定义方式有好几种,包括使用provider方法、使用factory方法,使用service方法。它们之间的区别暂且不关心。我们现在只要能创建一个服务出来就可以了。我使用了factory方法。一个需要注意的地方是,框架提供的服务名字都是由$开头的,所以我们自己定义的最好不要用$开头,防止发生命名冲突。
定义好一个服务后,我们就可以在控制器中声明使用了,如下:

app.controller('testC', function($scope, tpls) {
    $scope.question = questionModel;
    $scope.nowTime = new Date().valueOf();
    $scope.templates = tpls; //赋值到$scope中
    $scope.addOption = function() {
        var o = { content: '' };
        $scope.question.options.push(o);
    };
    $scope.delOption = function(index) {
        $scope.question.options.splice(index, 1);
    };
});

此时,若在模板中书写如下代码,我们便可以获取到服务tpls所提供的数据了:
模板:

<a href="javascript:void(0);" target="_blank" rel="nofollow">

13. 路由(route)
在谈路由机制前有必要先提一下现在比较流行的单页面应用,就是所谓的single page APP。为了实现无刷新的视图切换,我们通常会用ajax请求从后台取数据,然后套上HTML模板渲染在页面上,然而ajax的一个致命缺点就是导致浏览器后退按钮失效,尽管我们可以在页面上放一个大大的返回按钮,让用户点击返回来导航,但总是无法避免用户习惯性的点后退。解决此问题的一个方法是使用hash,监听hashchange事件来进行视图切换,另一个方法是用HTML5的history API,通过pushState()记录操作历史,监听popstate事件来进行视图切换,也有人把这叫pjax技术。基本流程如下:
如此一来,便形成了通过地址栏进行导航的深度链接(deeplinking ),也就是我们所需要的路由机制。通过路由机制,一个单页应用的各个视图就可以很好的组织起来了。


13.1 ngRoute内容
ng的路由机制是靠ngRoute提供的,通过hash和history两种方式实现了路由,可以检测浏览器是否支持history来灵活调用相应的方式。ng的路由(ngRoute)是一个单独的模块,包含以下内容:
l 服务$routeProvider用来定义一个路由表,即地址栏与视图模板的映射
l 服务$routeParams保存了地址栏中的参数,例如{id : 1, name : ‘tom’}
l 服务$route完成路由匹配,并且提供路由相关的属性访问及事件,如访问当前路由对应的controller
l 指令ngView用来在主视图中指定加载子视图的区域
以上内容再加上$location服务,我们就可以实现一个单页面应用了。下面来看一下具体如何使用这些内容。

13.2 ng的路由机制
第一步:引入文件和依赖
ngRoute模块包含在一个单独的文件中,所以第一步需要在页面上引入这个文件,如下:

<script src="http://code.angularjs.org/1.2.8/angular.min.js" rel="nofollow"/>
<script src="http://code.angularjs.org/1.2.8/angular-route.min.js" rel="nofollow"/>

光引入还不够,我们还需在模块声明中注入对ngRoute的依赖,如下:

var app = angular.module('MyApp', ['ngRoute']);

完成了这些,我们就可以在模板或是controller中使用上面的服务和指令了。下面我们需要定义一个路由表。
第二步:定义路由表
$routeProvider提供了定义路由表的服务,它有两个核心方法,when(path,route)和otherwise(params),先看一下核心中的核心when(path,route)方法。
when(path,route)方法接收两个参数,path是一个string类型,表示该条路由规则所匹配的路径,它将与地址栏的内容($location.path)值进行匹配。如果需要匹配参数,可以在path中使用冒号加名称的方式,如:path为/show/:name,如果地址栏是/show/tom,那么参数name和所对应的值tom便会被保存在$routeParams中,像这样:{name : tom}。我们也可以用进行模糊匹配,如:/show/:name将匹配/showInfo/tom。
route参数是一个object,用来指定当path匹配后所需的一系列配置项,包括以下内容:

l controller //function或string类型。在当前模板上执行的controller函数,生成新的scope;
l controllerAs //string类型,为controller指定别名;
l template //string或function类型,视图z所用的模板,这部分内容将被ngView引用;
l templateUrl //string或function类型,当视图模板为单独的html文件或是使用了

最简单情况,我们定义一个html文件为模板,并初始化一个指定的controller:

function emailRouteConfig($routeProvider) {
    $routeProvider.when('/show', {
        controller: ShowController,
        templateUrl: 'show.html'
    }).
    when('/put/:name', {
        controller: PutController,
        templateUrl: 'put.html'
    });
};

otherwise(params)方法对应路径匹配不到时的情况,这时候我们可以配置一个redirectTo参数,让它重定向到404页面或者是首页。
第三步:在主视图模板中指定加载子视图的位置
我们的单页面程序都是局部刷新的,那这个“局部”是哪里呢,这就轮到ngView出马了,只需在模板中简单的使用此指令,在哪里用,哪里就是“局部”。例如:

<div ng-view></div>

或:

<ng-view></ng-view>

我们的子视图将会在此处被引入进来。完成这三步后,你的程序的路由就配置好了。

13.3 路由示例
下面我们将用一个例子(例09)来说明路由的使用方式及步骤:
为demoApp添加一个路由,代码如下:

demoApp.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/list', {
        templateUrl: 'route/list.html',
        controller: 'routeListController'
    }).when('/list/:id', {
        templateUrl: 'route/detail.html',
        controller: 'routeDetailController'
    }).otherwise({
        redirectTo: '/list'
    });
}]);

/list 对应为:route/list.html页面,显示用户列表;/list/:id对应于route/detail.html页面,显示用户详细信息。


为list.html和detail.html分别声明Controller:routeListController和routeDetailController。

demoApp.controller('routeListController', function($scope) {
    $scope.users = [{ userId: "zhangsan", userName: "张三", userInfo: "我是张三,我为自己带盐!" },
        { userId: "lisi", userName: "李四", userInfo: "我是李四,我为卿狂!" },
        { userId: "woshishui", userName: "我是谁", userInfo: "我是谁!我是谁!我是谁!" }
    ];

});
demoApp.controller('routeDetailController', function($scope, $routeParams, userService) {
    $scope.userDetail = userService.getUser($routeParams.id);
});

routeDetailController中如上面提到的一样,注入了userService服务,在这里直接拿来用。

创建list.html和detail.html页面,代码如下:

<hr/>
<h3>Route : List.html(用户列表页面)</h3>
<ul>
    <li ng-repeat="user in users">
        <a href="http://m.cnblogs.com/142260/3817063.html?full=1#/list/{{ user.userId }}" target="_blank" rel="nofollow">
    </li>
</ul>
<hr/>

<h3>Route : detail.html(用户详细信息页面)</h3>
<h3>用户名:<span style="color: red;">{{userDetail.userName}}</span></h3>
<div>
    <span>用户ID:{{userDetail.userId}}</span><span>用户名:{{userDetail.userName}}</span>
</div>
<div>
    用户简介:<span>{{userDetail.userInfo}}</span>
</div>
<div>
    <a href="http://m.cnblogs.com/142260/3817063.html?full=1#/list" target="_blank" rel="nofollow">返回</a>
</div>

路由局部刷新位置:

<h1>AngularJS路由(Route) 示例</h1>
<div ng-view></div>

14. NG动画效果
NG动画效果,现在可以通过CSS3或者是JS来实现,如果是通过JS来实现的话,需要其他JS库(比如JQuery)来支持,实际上底层实现还是靠其他JS库,只是NG将其封装了,
使其更易使用。
NG动画效果包含以下几种:

  • enter:元素添加到DOM中时执行动画;
  • leave:元素从DOM删除时执行动画;
  • move:移动元素时执行动画;
  • beforeAddClass:在给元素添加CLASS之前执行动画;
  • addClass:在给元素添加CLASS时执行动画;
  • beforeRemoveClass:在给元素删除CLASS之前执行动画;
  • removeClass:在给元素删除CLASS时执行动画。

其相关参数为:

var ngModule = angular.module('YourApp', ['ngAnimate']);
demoApp.animation('.my-crazy-animation', function() {
    return {
        enter: function(element, done) {
            //run the animation here and call done when the animation is complete
            return function(cancelled) {
                //this (optional) function will be called when the animation
                //completes or when the animation is cancelled (the cancelled
                //flag will be set to true if cancelled).
            };
        },
        leave: function(element, done) {},
        move: function(element, done) {},
        //animation that can be triggered before the class is added
        beforeAddClass: function(element, className, done) {},
        //animation that can be triggered after the class is added
        addClass: function(element, className, done) {},
        //animation that can be triggered before the class is removed
        beforeRemoveClass: function(element, className, done) {},
        //animation that can be triggered after the class is removed
        removeClass: function(element, className, done) {}
    };
});

14.2 动画效果示例
下面我们来看下DEMO中的例子(例10)。
首先,我们在demoApp下定义一个动画效果,匹配CLASS:” .border-animation”

/*定义动画*/
demoApp.animation('.border-animation', function() {
    return {
        beforeAddClass: function(element, className, done) {
            $(element).stop().animate({
                'border-width': 1
            }, 2000, function() {
                done();
            });
        },
        removeClass: function(element, className, done) {
            $(element).stop().animate({
                'border-width': 50
            }, 3000, function() {
                done();
            });
        }
    };
});

动画效果的含义就是:在匹配CLASS为border-animation的元素添加一个CLASS之前使其边框的宽度在2秒内变为1PX;并在其移除一个CLASS时使其边框的宽度在3秒内变为50PX

视图中的代码如下(主要,其他相关样式请查看例子代码):

<div class="border-animation" ng-show="testShow"></div>
<a href="javascript:void(0);" target="_blank" rel="nofollow">

ng-show为false时会为其加上“ng-hide“的CLASS; ng-show为true时会为其移除“ng-hide“的CLASS,从而触发动画效果。


其他代码:

demoApp.controller("test10Controller", function($scope, $animate){
    $scope.testShow = true;
});

Goland 去掉每行前面弹出的小灯泡

修改配置文件,文件位置: C:\Users\Administrator\AppData\Roaming\JetBrains\GoLand2020.1\options

代码里添加一行(红色)

<application>
  <component name="DefaultFont">
    <option name="FONT_FAMILY" value="Courier New" />
    <option name="SECONDARY_FONT_FAMILY" value="SimSun" />
  </component>
  <component name="EditorSettings">
    <option name="USE_SOFT_WRAPS" value="MAIN_EDITOR" />
    <option name="SOFT_WRAP_FILE_MASKS" value="*.md; *.txt; *.rst; *.adoc;*.go;*.html;*.php" />
    <option name="USE_CUSTOM_SOFT_WRAP_INDENT" value="true" />
    <option name="IS_RIGHT_MARGIN_SHOWN" value="false" />
    <option name="SHOW_INTENTION_BULB" value="false" />
  </component>
</application>

保存,重启Goland。

 

linux top 命令详解 [Debian 9为例]

top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。

运行 top 命令后,CPU 使用状态会以全屏的方式显示,并且会处在对话的模式 — 用基于 top 的命令,可以控制显示方式等等。退出 top 的命令为 q (在 top 运行中敲 q 键一次)

内容解释:

第一行(top):
  15:24:36 系统当前时刻
  14 days 系统启动后到现在的运作时间
  3 users 当前登录到系统的用户,更确切的说是登录到用户的终端数 — 同一个用户同一时间对系统多个终端的连接将被视为多个用户连接到系统,这里的用户数也将表现为终端的数目
  load average 当前系统负载的平均值,后面的三个值分别为1分钟前、5分钟前、15分钟前进程的平均数,一般的可以认为这个数值超过 CPU 数目时,CPU 将比较吃力的负载当前系统所包含的进程

第二行(Tasks):
  288 total 当前系统进程总数
  1 running 当前运行中的进程数
  287 sleeping 当前处于等待状态中的进程数
  0 stoped 被停止的系统进程数
  0 zombie 僵尸进程数

第三行(Cpus):
  7.3% us 用户空间占用CPU百分比
  2.0% sy 内核空间占用CPU百分比
  0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
  90.4% id 空闲CPU百分比
  0.3% wa 等待输入输出的CPU时间百分比
  0.0% hi
  0.0% si
  0.0% st

第四行(Mem):
  2042616 total 物理内存总量
  1770116 used 使用的物理内存总量
  272500 free 空闲内存总量
  163912 buffers 用作内核缓存的内存量

第五行(Swap):

表示类别同第四行(Mem),但此处反映着交换分区(Swap)的使用情况。通常,交换分区(Swap)被频繁使用的情况,将被视作物理内存不足而造成的。
  2094076 total 交换区总量
  45052 used 使用的交换区总量
  2049024 free 空闲交换区总量
  346624 cached 缓冲的交换区总量

最下部分的进程列表栏:

以 PID 区分的进程列表将根据所设定的画面更新时间定期的更新。通过 top 内部命令可以控制此处的显示方式:
  PID:进程的ID
  USER:进程所有者
  PR:进程的优先级别,越小越优先被执行
  NInice:值
  VIRT:进程占用的虚拟内存
  RES:进程占用的物理内存
  SHR:进程使用的共享内存
  S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
  %CPU:进程占用CPU的使用率
  %MEM:进程使用的物理内存和总内存的百分比
  TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
  COMMAND:进程启动命令名称

top 运行中可以通过 top 的内部命令对进程的显示方式进行控制。内部命令如下表:
  s- 改变画面更新频率
  l – 关闭或开启第一部分第一行 top 信息的表示
  t – 关闭或开启第一部分第二行 Tasks 和第三行 Cpus 信息的表示
  m – 关闭或开启第一部分第四行 Mem 和 第五行 Swap 信息的表示
  N – 以 PID 的大小的顺序排列表示进程列表(第三部分后述)
  P – 以 CPU 占用率大小的顺序排列进程列表 (第三部分后述)
  M – 以内存占用率大小的顺序排列进程列表 (第三部分后述)
  h – 显示帮助
  n – 设置在进程列表所显示进程的数量
  q – 退出 top
  s -改变画面更新周期

ECHARTS添加滑动条(dataZoom)拖动显示问题

由于数据量比较大,采用了隐藏总时间轴,主图表显示dataZoom滑动选择时间区域的数据曲线的方式来展示数据;数据通过websocket传输;这里涉及到一个得到新数据后,图表重载,时间轴选择区域也被重置的问题,所以得到新数据后,需要把新时间段重新传值进图表option里面去,重载的时候才不会每次都回到初始的选择时间段。

dataZoom: [
{
show: true,type: 'slider', realtime: false, xAxisIndex:1 ,
startValue:zoomsv, endValue:zoomev, bottom: 10, backgroundColor:'#F5F5F5',
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '70%',
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2
},
textStyle:{ color:'red' }
} ],

设置了 dataZoom 的 startValue 和 endValue 后,新问题又出现了。

拖动选择时两端的日期值不会跟着变化;

看官网例子都是设置的 start值和 end值,按例子修改后,果然问题得到了解决。

dataZoom: [
{ //
suteut 通过具体日期与总时间段的时间值计算得到的百分比
show: true,type: 'slider', realtime: false, xAxisIndex:1 , start:sut, end:eut, bottom: 10, backgroundColor:'#F5F5F5',
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '70%',
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2
},
textStyle:{ color:'red' }
} ],

SVN 服务器迁移记录

写在前面:

两服务器均为Debian系统,原服务器subversion版本(svnadmin –version):version 1.8.10 (r1615264),新服务器版本:version 1.9.5 (r1770682);

1、原服务器备份:

user@debian:~# svnadmin dump /home/subver/xxx > xxx.dump

将生成的备份文件转移至新服务器

2、新服务器安装subversion

user@debian:~# apt-get install subversion

3、新服务器导入原服务器备份文件

创建项目文件

user@debian:~# svnadmin create /home/subver/xxx

修改配置文件 /home/subver/xxx/conf/svnserve.conf : 去掉anon-access = read、auth-access = write、password-db = passwd 三行前面的 # 和空格

修改配置文件 /home/subver/xxx/conf/passwd : 新加入一行 : 你的用户名 user = 密码

导入备份文件

user@debian:~# svnadmin load /home/subver/xxx < xxx.dump

4、启动svn服务

user@debian:~# svnserve -d -r /home/subver –listen-port 8000

Access denied for user ‘xxx ‘@’localhost’ (using password: YES) ThinkPHP

老站点,TP3.2开发的,最近转移到新服务器,检查数据库名、账号密码等各项配置都没错,却依旧出现下面错误提示:

Access denied for user ‘xxx ‘@’localhost’ (using password: YES) ThinkPHP

将数据库连接地址 localhost 更改成 127.0.0.1 ,, 问题依旧;

将PHP版本降回php5.3,,问题依旧;

清空 /app/Runtime/ 目录,,问题解决。准确来说 是 删除了 /app/Runtime/common~runtime.php 这个文件之后,网站可以正常访问了 。

mysqldump 备份数据库

root@debian:~# mysqldump -u*** -p*** –database xxx > /root/xxx.sql
Warning: Using unique option prefix database instead of databases is deprecated and will be removed in a future release. Please use the full name instead.

root@debian:~# mysqldump -h localhost -p 3306 -u*** -p*** –database xxx > /www/xxx.sql
Warning: Using unique option prefix database instead of databases is deprecated and will be removed in a future release. Please use the full name instead.
mysqldump: Got error: 1044: Access denied for user ‘mall_hec8_com’@’localhost’ to database ‘3306’ when selecting the database

root@debian:~# mysqldump -u*** -p*** xxx > /www/xxx.sql
root@debian:~#