分类
Linux

使用Hugo 搭建静态博客

Hugo是一个用Go语言编写的,和Jekyll一样,都是静态博客生成系统,将markdown转换为静态网页。同样的,我们也可以将生成的网页托管到Github Pages。

安装 Hugo

官网介绍的安装方法是mac平台的,但是在其它平台安装也是非常简单的,我们只需要在 Releases · gohugoio/hugo下载对应的版本:

1)Windows版本,下载ZIP压缩包

然后将下载的压缩包解压至任意路径,再将此路径添加至系统环境变量Path即可,

2)Linux平台就更加简单了,比Jekyll和Hexo都更加容易,对于大部分的发行版,都在官方源添加了Hugo,可以直接使用包管理器安装它们:

对于Ubuntu:

# apt-get install hugo

但是这样安装可以会安装到旧的版本,例如我在Ubuntu 16.04上直接安装,查询版本

$ hugo version
Hugo Static Site Generator v0.16-DEV BuildDate: 2016-02-07T01:14:17+08:00

安装到了0.16版本,所以我推荐到Github下载最新版本:Releases · gohugoio/hugo

可以直接下载deb包安装。

对于Archer,直接就可以安装到最新版本

# pacman -S hugo
$ hugo version
Hugo Static Site Generator v0.26 linux/amd64 BuildDate: 2017-08-07T18:27:14+02:00

如何使用

使用如下命令创建一个不包含主题的站点

$ hugo new site quickstart

目录结构

quickstart
├── archetypes
├── config.toml        ##配置文件
├── content            ##文章放置文件夹
├── data
├── layouts
├── static
└── themes             ##主题文件夹

进入到站点目录下并安装主题

$ cd quickstart
$ git init
$ git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke

编辑配置文件,设置主题

$ echo 'theme = "ananke"' >> config.toml

创建一篇文章

hugo new posts/my-first-post.md

my-first-post.md 自动生成到了 content/my-first-post.md ,打开 my-first-post.md 看下:

+++
date = "2015-10-25T08:36:54-07:00"
draft = true
title = "about"
+++
正文内容

内容是 Markdown 格式的,+++ 之间的内容是 TOML 格式的,根据你的喜好,你可以查询官方文档换成 YAML 格式(使用 — 标记)或者 JSON 格式。

OK~

运行站点

$ hugo server -D
Started building sites ...
Built site for language en:
0 draft content
0 future content
0 expired content
0 regular pages created
6 other pages created
0 non-page files copied
0 paginator pages created
0 categories created
0 tags created
total in 7 ms
Watching for changes in /home/zrdn_link migration/Desktop/hugo-demo/quickstart/{data,content,layouts,static,themes}
Serving pages from memory
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

打开浏览器,输入http://localhost:1313/,即可看到站点已经运行了

部署

可以通过下面的命令生成静态页面

$ hugo --theme=hyde --baseUrl="http://YOURNAME.github.io/"

所有的静态文件会生成到public文件夹内,然后推送到仓库

$ cd public
$ git init
$ git remote add origin https://github.com/YOURNAME/YOURNAME.github.io.git
$ git add -A
$ git commit -m "first commit"
$ git push -u origin master

然后即可通过YOURNAME.github.io访问到站点啦。

分类
Linux

Arch Linux 安装 Jekyll

补充一个:

Archlinux可以直接用pacman安装ruby-jekyll,但是通常这样使用会报错,原因是需要安装一些gem依赖,例如sass等,安装完ruby-jekyll再用gem安装一下需要的包就好了

我推荐如果用gem安装jekyll出错时干脆用pacman安装,虽然这样安装的版本会比较低,但是很稳,因为arch的源太新,经常滚到最新的rubydev版本,所以有时候jekyll会报错,pacman安装的则不会。

在我印象中,在Windows或者Ubuntu等系统中安装完Ruby即可使用

$ gem install jekyll

这条命令来安装好jekyll,通常是没有错误并可以直接使用的。

但是刚才在Archlinux中安装之前我的记忆来安装Jekyll,在运行时却是报错的:

$ jekyll -v
-zsh: jekyll: command not found

通常,提示一个命令没有发现,就会想到是当前shell中没有添加命令路径,我切换到bash同样也是报错。

其实这是一个很简单的错误,只要把变量路径添加到当前shell的配置文件即可

对于bash,请添加~/.bashrc,对于zsh,添加到~/.zshrc

PATH="$(ruby -e 'print Gem.user_dir')/bin:$PATH"
GEM_HOME=$(ls -t -U | ruby -e 'puts Gem.user_dir')
GEM_PATH=$GEM_HOME
export PATH=$PATH:$GEM_HOME/bin

然后还需要安装bundle

$ gem install bundle

但是还是会报错,同上

$ bundle -v
-zsh: bundle: command not found

照样需要添加路径,但是路径不同

export PATH=$PATH:/root/.gem/ruby/2.4.0/bin

添加完路径后执行

$ source .zshrc  ## 或者.bashrc

更新配置文件即可。

分类
Linux

在Arch Linux 中搭建LAMP环境

简单的概括一下在Arch Linux中如何搭建LAMP环境。

安装 Apache

安装Apache有两种方式:

一是编译安装,在官网下载Apache httpd 压缩包,然后解压,编译安装。Download – The Apache HTTP Server Project

这种安装方法适用于各类发行版。

## 编译安装三部曲
$ ./configure
$ make
$ make install

另外一种方法就是直接使用pacman包管理器安装了,简单方便,我是使用这种方法安装的。Arch Linux wiki也是介绍的这种方法。Apache HTTP Server – ArchWiki

# pacman -S apache

启动 Apache

# systemctl start httpd

然后访问http://127.0.0.1即可看到一个文件浏览的页面了

使用这个命令可以查看当前httpd的状态以及排错。

# systemctl status httpd

使用这个命令将httpd加入开机自动启动

# systemctl enable httpd

安装 PHP

同样的也可以使用下载安装,但是我这里直接使用pacman安装了。

# pacman -S php php-apache

配置 PHP

php-apache 中包含的 libphp7.so 不支持 mod_mpm_event,仅支持 mod_mpm_prefork。需要在 /etc/httpd/conf/httpd.conf中注释掉:

#LoadModule mpm_event_module modules/mod_mpm_event.so

然后取消下面行的注释:

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

启用 PHP

/etc/httpd/conf/httpd.conf 中添加如下行:

将这一行放在LoadModule的末尾:

LoadModule php7_module modules/libphp7.so
AddHandler php7-script php

将这一行放到Include列表的末尾:

Include conf/extra/php7_module.conf

重启 httpd.service。

systemctl restart httpd

这次重启会有点长,如果你一下就好了,那就就是出错了,请运行上面提到的命令查看原因。

安装 MariaDB

MariaDB完全兼容mysql。

# pacman -S mariadb libmariadbclient mariadb-clients

配置 MariaDB

安装Mariadb软件包之后,你必须运行下面这条命令:

# mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql

接着执行

# systemctl start mariadb
# mysql_secure_installation
# systemctl restart mariadb

第二条命令会提示设置root密码。

取消 /etc/php/php.ini中 下面行前面的注释 :

extension=pdo_mysql.so
extension=mysqli.so

完成后 重启 httpd.service 服务。

# systemctl restart httpd

安装 phpMyAdmin

管理 MariaDB的方法有很多,wiki提到phpMyAdmin和MariaDB不完全兼容,但是足够执行基本任务。

安装 phpMyAdmin 也有两种方法:

一是使用包管理安装

# pacman -S phpmyadmin

但是我不推荐这个方法,配置复杂,而且wiki很多内容已经过时。

我推荐直接下载phpmyadmin的压缩包解压到需要的目录

这种方法简单快捷的多。

直接在phpMyAdmin官网下载安装压缩包,解压到网站目录即可访即可。

结束

这里是非常简单的概括了一下安装步骤,很多拓展功能没有提及,比如常用的为Apache开启.htccess支持,开启多虚拟主机等等。

想要了解更多可以访问wiki,但有些内容已经不适用了,自行斟酌。

分类
使用笔记

Angularjs入门学习(七)路由

路由(route),几乎所有的MVC(VM)框架都应该具有的特性,因为它是前端构建单页面应用(SPA)必不可少的组成部分。

路由只是从一个页面重定向到另一个页面。在任何web应用中路由都很重要。AngularJs是一个单页面应用程序,一旦应用程序加载,它永远不会重新加载。在这种情况下我们如何实现路由?我们可以使用指令模板从一个模板导航到另一个模板,但是最好不要这样做,而是将视图限制在布局和模板视图中,并以URL显示模板视图。

看一个实例:

<body ng-app="myApp">
<p><a href="#/!">Main</a></p>
<a href="#!red">Red</a>
<a href="#!green">Green</a>
<a href="#!blue">Blue</a>
<div ng-view></div>
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
    $routeProvider
    .when("/", {
        templateUrl : "main.htm"
    })
    .when("/red", {
        templateUrl : "red.htm"
    })
    .when("/green", {
        templateUrl : "green.htm"
    })
    .when("/blue", {
        templateUrl : "blue.htm"
    });
});
</script>
</body>

当Red被点击时,<div ng-view></div>中会载入red.htm文件中的内容

整个过程中页面不需要重新加载。

ng-view

ng-view 是ngRoute中包含的一个特殊指令。它相当与一个占位符,表示即将载入页面的位置。

有三种不同的方式可以达到效果:

  • <div ng-view></div>
  • <ng-view></ng-view>
  • <div class="ng-view"></div>

应用程序只能有一个ng-view指令.

$routeProvider

$routeProvider是配置在应用程序的config部分配置路由的提供程序服务,使用$routeProvider您可以定义当用户点击一个链接,显示的页面。

定义$routeProvider的例子

var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
    $routeProvider
    .when("/", {
        templateUrl : "main.htm"
    })
    .when("/london", {
        templateUrl : "london.htm"
    })
    .when("/paris", {
        templateUrl : "paris.htm"
    });
});

controller

随着$routeProvider的使用,你可以定义每个视图的控制器

var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
    $routeProvider
    .when("/", {
        templateUrl : "main.htm"
    })
    .when("/london", {
        templateUrl : "london.htm",
        controller : "londonCtrl"   //添加控制器
    })
    .when("/paris", {
        templateUrl : "paris.htm",
        controller : "parisCtrl"    //添加控制器
    });
});
app.controller("londonCtrl", function ($scope) {
    $scope.msg = "I love London";
});
app.controller("parisCtrl", function ($scope) {
    $scope.msg = "I love Paris";
});

然后你可以在london.htm或者paris.htm中使用{{ msg }}

london.htm

<p>{{ msg }}</p>    // I love London

template

在前面的例子中,我们在$routeProvider.when中使用了templateUrl,这个参数用来插入HTML文件

$routeProvider.when('/computers', {
    templateUrl: 'views/computers.html',
});

以上代码会从服务端获取 views/computers.html 文件内容插入到 ng-view 中。

otherwise

在$routeProvider中还有个otherwise方法

var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
   $routeProvider
    .when("/banana", {
        template : "<h1>Banana</h1><p>Bananas contain around 75% water.</p>"
    })
    .when("/tomato", {
        template : "<h1>Tomato</h1><p>Tomatoes contain around 95% water.</p>"
    })
    .otherwise({
        template : "<h1>Nothing</h1><p>Nothing has been selected</p>"
    });
});

上面的例子中,倘若既不是banana又不是tomato的链接被点击时,就会插入

分类
Linux

WordPress 伪静态规则(IIS/Apache/Nginx)

不少朋友总是询问 WordPress 如何添加伪静态规则,今天倡萌就总结一下 IIS/Apache/Nginx 三种环境下的伪静态规则,希望对大家有所帮助。

检测主机是否支持伪静态的方法:在WP后台 > 设置 > 固定链接,设置为 非默认带?的那种结构,然后访问任何一篇文章,如果出现 404 错误,说明你的主机当前不支持 WordPress 伪静态。

IIS伪静态规则

IIS 环境是 Windows 主机常用的服务器环境,新建一个 txt 文件,将下面的代码添加到文件中:

[ISAPI_Rewrite]
# Defend your computer from some worm attacks
#RewriteRule .*(?:global.asa|default\.ida|root\.exe|\.\.).* . [F,I,O]
# 3600 = 1 hour
CacheClockRate 3600
RepeatLimit 32
# Protect httpd.ini and httpd.parse.errors files
# from accessing through HTTP
# Rules to ensure that normal content gets through
RewriteRule /tag/(.*) /index\.php\?tag=$1
RewriteRule /software-files/(.*) /software-files/$1 [L]
RewriteRule /images/(.*) /images/$1 [L]
RewriteRule /sitemap.xml /sitemap.xml [L]
RewriteRule /favicon.ico /favicon.ico [L]
# For file-based wordpress content (i.e. theme), admin, etc.
RewriteRule /wp-(.*) /wp-$1 [L]
# For normal wordpress content, via index.php
RewriteRule ^/$ /index.php [L]
RewriteRule /(.*) /index.php/$1 [L]

然后另存为 httpd.ini 文件,上传到WordPress站点的根目录即可。

Apache伪静态规则

Apache是 Linux 主机下常见的环境,现在一般的 Linux 虚拟主机都采用这种环境。新建一个 htaccess.txt 文件,添加下面的代码:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

然后上传到 WordPress 站点的根目录,重命名为 .htaccess 即可

Nginx伪静态规则

Nginx环境一般是Linux 主机 VPS或服务器用户用的比较多,这些用户一般都会自己配置Nginx,或者有专门的人帮你配置,打开 nginx.conf 或者某个站点的配置环境,比如 wpdaxue.com.conf(不同人配置的不一样),在 server { } 大括号里面添加下面的代码:

location / {
if (-f $request_filename/index.html){
                rewrite (.*) $1/index.html break;
        }
if (-f $request_filename/index.php){
                rewrite (.*) $1/index.php;
        }
if (!-f $request_filename){
                rewrite (.*) /index.php;
        }
}

保存,重启 Nginx 即可。

题外话:倡萌一直不推荐在 windows 的IIS服务器下安装 WordPress,因为 IIS 环境运行php程序的效率,相对同等配置下 Linux 的 Apache 和 Nginx 环境,要低的多,具体可以看看https://www.wpdaxue.com/wordpress-hosting.html

转载于https://www.wpdaxue.com/wordpress-rewriterule.html

分类
碎碎念

Angularjs入门学习(六)表单

AngularJS 表单是输入控件的集合。

HTML 控件

以下 HTML input 元素被称为 HTML 控件:

  • input 元素
  • select 元素
  • button 元素
  • textarea 元素

ng中的表单与Controller

看这个小标题也行你会差异,表单验证,怎么跟controller扯上关系了。ng中的form已经不同于我们平时用的form标签,做了增强。form是FormController的一个实例。如何理解这句话呢?想想我们使用ng-controller指令的情景:

<div ng-controller="testC">
  <input type="test" ng-model="a" />
</div>
<scritp>
function testC($scope){
  //.............
}
</script>

应用了ng-controller的div就是testC的一个实例,我们可以在模板中使用定义在$scopt上的任何属性和方法,而testC的定义也是由我们自己实现的。当我们使用<form>的时候也是这样的道理,FormController由ng为我们定义好了,有一系列属性和方法提供给我们完成验证工作,form实例通过name属性来进行标识,我们可以通过此标识来访问form实例的属性和方法,如:

<form name="myform">
  {{ myform.$valid }}
</form>

form提供的属性都是用来表示表单的验证状态的,包括:$pristine(表单没有填写记录)、$dirty(表单有填写记录)、$valid(通过验证)、$invalid(未通过验证)、$error(验证错误信息)。除$error外,前四个的值为true或false表示相应的状态。$error的值为一个js对象,包含了以下验证内容的状态:

  • email
  • max
  • maxlength
  • min
  • minlength
  • number
  • pattern
  • required
  • url

这些内容我们会在稍后的例子中看到。FormController还提供了一些方法,我们一般不手工调用它们,都是系统自己调用。可参考官方文档:http://docs.angularjs.org/api/ng.directive:form.FormController

表单元素,如input、checkbox、radio等也不是普通的表单元素了,它们通通是NgModelController的实例。与form一样,也是通过name属性来标识。FormController拥有的那五个属性,NgModelController也同样拥有,除此之外,还有许多额外的属性和方法,我们稍后也在示例中展示,可参考官方文档:http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController

还有一个特性需要了解,一个表单中的表单元素,会作为这个form的属性自动加在上面,通过name标识就可以访问到,如:

<form name="myform">
  <input type="text" name="myname" />
  {{myform.myname.$valid}}
</form>

表单绑定实例

<div ng-app="" ng-controller="formController">
  <form novalidate>
    First Name:<br>
    <input type="text" ng-model="user.firstName"><br>
    Last Name:<br>
    <input type="text" ng-model="user.lastName">
    <br><br>
    <button ng-click="reset()">RESET</button>
  </form>
  <p>form = {{user}}</p>
  <p>master = {{master}}</p>
</div>
<script>
function formController ($scope) {
    $scope.master = {firstName: "John", lastName: "Doe"};
    $scope.reset = function() {
        $scope.user = angular.copy($scope.master);
    };
    $scope.reset();
};
</script>

实例解析

AngularJS ng-model 指令用于绑定 input 元素到模型中。

模型对象 master 的值为 {"firstName" : "John", "lastName" : "Doe"}

模型函数 reset 设置了模型对象 user 等于 master。

AngularJS提供可与HTML控件相关联的多个事件。例如ng-click通常与按钮相关联。以下是AngularJS支持的事件。

  • ng-click
  • ng-dbl-click
  • ng-mousedown
  • ng-mouseup
  • ng-mouseenter
  • ng-mouseleave
  • ng-mousemove
  • ng-mouseover
  • ng-keydown
  • ng-keyup
  • ng-keypress
  • ng-change

ng内置的验证规则

ng框架提供了非常方便的验证机制,你只需要在标签上加点指令,像使用HTML5提供的验证那样,然后在css中根据规则定义好正确/错误的样式就OK了,例如我们要让一个文本框为必填项,使用required:

<form name="myform novalidate">
  <input type="text" ng-model="a" required />
</form>

有几点需要注意:

1、在<form>上加了一个novalidate,用来禁止掉浏览器默认的验证行为,因为ng已经对HTML5的几种表单新特性做了兼容处理。

2、表单元素必须有ng-model,否则无法触发验证

3、在css中分别定义.ng-pristine.ng-valid.ng-invalid.ng-dirty这四种样式,ng会根据相应的状态自动加上样式。

只在提交表单后显示错误信息

有时候不想在用户正在输入的时候显示错误信息. 当前错误信息会在用户输入表单时立即显示. 由于Angular很棒的数据绑定特性,这是可以发生的. 因为所有的事务都可以在一瞬间发生改变,这在表单验证时会有副作用.

对于你想要只在表单正要提交之后才显示错误消息的场景, 你就需要对上面的代码做一些小调整.

1、你要去掉提交按钮上的ng-disabled,因为我们想要用户即使是在表单没有全部验证完的情况下也能点击提交.

2、你要在表单已经被提交之后添加一个变量. 在你的 submitForm() 函数中, 只要加入 $scope.submitted = true 就行了;. 一旦表单被提交,它就会保存提交值为true的submitted变量.

3、将错误规则从ng-class="{ 'has-error' : userForm.name.$invalid && !userForm.name.$pristine }" 调整为 ng-class="{ 'has-error' : userForm.name.$invalid && !userForm.name.$pristine && submitted }". 这就确保了错误消息只会在表单被提交时被显示出来. 你也许会需要为这个变量调整所有其它的 ng-class 和 ng-show.

现在,只有在submitted变量被设置为true时才会显示错误信息.

分类
JavaScript

AngularJS入门学习(五)事件

这里讲一下AngularJS比较简单的几个事件,包括ng-click``ng-selected``ng-change

ng-click

ng-click指令用来定义HTML元素被点击后触发的事件。

<div ng-app="">
  <button ng-click="count = count + 1" ng-init="count = 1">ClickMe</button>
  <p>{{ count }}</p>
</div>

上面的click定义了一个表达式(expression)每次点击button后,count便加一。

ng-click事件还可以触发一个函数

<div ng-app="myapp" ng-controller="myCtrl">
  <button ng-click="click()">clickFun</button>
</div>
<script type="text/javascript">
  var app = angular.module("myapp",[]);
  app.controller("myCtrl",function($scope){
    $scope.click = function(){
      alert("you clicked me!");
    }
  })
</script>

上面的实例展示了当Button被点击时触发一个函数的例子。

ng-selected

ng-selected 指令用于设置<select>列表中的 <option> 元素的 selected 属性。ng-selected 属性的表达式返回 true 则选项被选中。

<div ng-app="">
  点击复选框选择 BMW 选项:
  <input type="checkbox" ng-model="mySel">
  <p>我喜欢的车:</p>
  <select>
    <option>Volvo</option>
    <option ng-selected="mySel">BMW</option>
    <option>Ford</option>
  </select>
</div>

上面的例子展示了当checkbox被选中时,即mySeltrue时,ng-seletedmySel的选项被选中。

ng-change

ng-change指令定义了当HTML元素改变的时候触发的事件。

ng-change需要搭配ng-model指令使用。

<div ng-app="myapp" ng-controller="myCtrl">
  <input type="text" ng-change="myFunc()" ng-model="myValue" />
  <p>The input field has changed {{ count }} times.</p>
</div>
<script type="text/javascript">
var app = angular.module("myapp",[]);
app.controller("myCtrl",function($scope){
  $scope.count = 0;
  $scope.myFunc = function(){
    $scope.count++;
  }
})
</script>

上面的例子演示了当输入框内内容改变时触发函数来改变count值。

(完)

分类
JavaScript

AngularJS入门学习(四)常用服务

AngularJS Service是一个函数或对象,可以使用在Angular应用中。

AngularJS有很多内置服务,我们也可以按照自己的需要来创建服务,这里讲一下几个常用的服务。

$HTTP

$http服务是所有Angular服务中最为常用的内置服务之一。

$http服务封装了浏览器原生的XMLHttpRequest对象。它只能接受一个参数,且这个参数是一个对象,包含了用来生成HTTP请求的配置内容。它返回一个Promise对象(一个原生的ES6对象,表示即将发生的事件),具有两个方法(success和error)。

$http({
  url:'data.json',
  method:'GET'
}).success(function(response){
  //响应成功
}).error(function(response){
  //处理响应失败
});

使用than方法来处理回调

$http({
  method: 'GET',
  url: 'data.js'
}).then(function successCallback(response) {
  //响应成功
  }, function errorCallback(response) {
  //处理响应失败
});

快捷的GET/POST请求

$http.get('date.json', config).then(successCallback, errorCallback);
$http.post('date.json', data, config).then(successCallback, errorCallback);

$location

Angular中使用内置的$location服务来监听、操作URL,包括如下功能:

  • 获取、监听、改变地址栏的URL
  • 与URL实现双向数据绑定(地址栏变动、前进后退或者点击页面的链接均会触发)
  • 将URL对象封装成了一套方法(protocol、host、port、path、search和hash)

$location服务的具体行为取决于它初始化时的配置。默认设置对大多数应用都是适合的,你也可以自定义配置来增加些新特性。

$location服务初始化好以后,你就可以使用jquery风格的读写器和它交互了,你可以获取或者改变当前URL。

$location服务的配置

要配置$location服务,检索$locationProvider并把参数设置成以下这样:

html5Mode(模式): {boolean}
  strue - 参阅HTML5模式
  false - 参阅Hashbang模式
  default: false
hashPrefix(前缀): {string}
  Hashbang URLs的前缀 (在Hashbang模式中或者低级浏览器中使用)
  default: '!'

配置示例

$locationProvider.html5Mode(true).hashPrefix('!');

Hashbang和HTML5模式

$location服务有两种用来控制地址栏URL格式的配置:Hashbang模式(默认)和HTML5模式(使用HTML5历史API)。应用会使用两种模式中相同的API。

示例

Hashbang模式(默认mode)

使用这个模式的话,$location会在所有浏览器中使用Hashbang URLs。

it('should show example', inject(
  function($locationProvider) {
  $locationProvider.html5mode = false;
  $locationProvider.hashPrefix = '!';
  },
  function($location) {
  // open http://host.com/base/index.html#!/a
  $location.absUrl() == 'http://host.com/base/index.html#!/a'
  $location.path() == '/a'
  $location.path('/foo')
  $location.absUrl() == 'http://host.com/base/index.html#!/foo'
  $location.search() == {}
  $location.search({a: 'b', c: true});
  $location.absUrl() == 'http://host.com/base/index.html#!/foo?a=b&c'
  $location.path('/new').search('x=y');
  $location.absUrl() == 'http://host.com/base/index.html#!/new?x=y'
  }
));

支持网络爬虫

你需要添加特别的meta标记在你的文档的头部才能支持对你的AJAX应用的索引。

<meta name="fragment" content="!" />

这能让网络爬虫请求带有_escaped_fragment_形式的参数链接,这样你就能识别爬虫并且返回一个HTML的快照了。更多信息请参考 Making AJAX Applications Crawlable

HTML5模式

在HTML5模式中,$location服务的读写器和浏览器的URL地址通过HTML5历史API交互,这使你能用regular URL path并且搜索各组成部分,和hashbang是等效的。 如果浏览器不支持HTML5 历史API, $location服务会自动回退成使用hashbang URLs。你就不用担心浏览器的支持性了。$location服务总是会用最好的选择。

  • 在低级浏览器中使用了regular URL -> 重定向成hashbang URL
  • 在现代浏览器中打开了一个hashbang URL -> 重写成regular URL
it('should show example', inject(
  function($locationProvider) {
  $locationProvider.html5mode = true;
  $locationProvider.hashPrefix = '!';
  },
  function($location) {
  // in browser with HTML5 history support:
  // open http://host.com/#!/a -> rewrite to http://host.com/a
  // (replacing the http://host.com/#!/a history record)
  $location.path() == '/a'
  $location.path('/foo');
  $location.absUrl() == 'http://host.com/foo'
  $location.search() == {}
  $location.search({a: 'b', c: true});
  $location.absUrl() == 'http://host.com/foo?a=b&c'
  $location.path('/new').search('x=y');
  $location.url() == 'new?x=y'
  $location.absUrl() == 'http://host.com/new?x=y'
  // in browser without html5 history support:
  // open http://host.com/new?x=y -> redirect to http://host.com/#!/new?x=y
  // (again replacing the http://host.com/new?x=y history item)
  $location.path() == '/new'
  $location.search() == {x: 'y'}
  $location.path('/foo/bar');
  $location.path() == '/foo/bar'
  $location.url() == '/foo/bar?x=y'
  $location.absUrl() == 'http://host.com/#!/foo/bar?x=y'
  }
));

$cacheFactory

$cacheFactory是应用程序一个会话(Session)中的缓存服务,以key-value对的方法存储一些临时数据。它跟浏览器本地缓存localStorage是不一样的。$cacheFactory在用户删除当前会话(比如强制刷新页面)之后,缓存的数据就被清空了。

用法

首先,要得到一个缓存实例,用id来区分,比如我想取id为’firstCache’的缓存:

var cache = $cacheFactory('firstCache');

添加kv对,put方法:

cache.put(key, value);

获取,get方法:

cache.get(key); // 如果不存在这个key的话,会返回undefined

添加kv对,put方法:

cache.put(key, value);

删除,remove和removeAll:

cache.remove(key); // 删除某个kv对
cache.removeAll(); // 删除该缓存的全部kv对

删除该缓存实例,destroy:

cache.destroy(); // 把当前缓存删除掉
cache.put(key, value); // 错误!不能再访问该缓存,要重新生产一个实例出来

$timeout、$interval

$timeout和$interval是AngularJS自带的服务,跟原生js中的setTimeout和setInterval函数的用法基本是一样的。但是有两个不一样的地方需要注意一下:

区别一:

原生js中的两个函数,如果在AngularJS中使用并且在回调函数中需要使用$scope服务的话,我们需要用$angular.$apply把回调函数包起来,因为这里setTimeout函数被AngularJS当作是外部函数了。就像这样:

// 错误的写法示例(使用setTimeout却没有用$apply):
angular.module('myDemo', [])
  .controller('firstController', ['$scope', function ($scope) {
  setTimeout(function () {
    console.log('before');  // 正常输出before
    $scope.name = "My name have been changed."; // 这一句不被执行
    console.log('after');   // 正常输出after
  }, 2000);
  }]);
// 正确的写法示例
angular.module('myDemo', [])
  .controller('firstController', ['$scope', function ($scope) {
  setTimeout(function () {
    console.log('before');  // 正常输出before
    $scope.$apply(function () {
    $scope.name = "My name have been changed.";  // 正确显示
    });
    console.log('after');   // 正常输出after
  }, 2000);
  }]);

所以,在AngularJS中,最好不要用setTimeout或setInterval,而是用那两个AngularJS系统服务。

区别二:

取消的方式不大一样,比如timeout:

// setTimeout
var id = setTimeout(func, 2000); // 返回该timeout的id
clearTimeout(id); // 使用clearTimeout
// $timeout服务
var promise = $timeout(f, 2000); // 返回一个promise对象
$timeout.cancel(promise); // 还是要使用服务,它的cancel方法

$sce

sce指的是Strict Contextual Escaping,它是默认开启的,负责拒绝一些不安全的行为,比如加载不同源的资源等等。但是有时候,我们又需要加载一些特定的资源,我们就得使用$sce的一些方法,来为这些资源和AngularJS系统之间建立信任。

用法

$sce有以下常用方法:

  • $sce.trustAsHtml(…):将一段html文本视为安全
  • $sce.trustAsUrl(…)
  • $sce.trustAsResourceUrl(…)
  • $sce.trustAsJs(…)

举个例子,假如我要显示(可以理解成渲染,相当于android SDK中的WebView)一段html文本表示的内容,我们需要遵循以下步骤:

1.在html模板中用“ng-bind-html”属性来绑定一个model(变量);

2.在js中注入$sce服务,并且使用方法$sce.trustAsHtml(…),把信任后的值赋给该model。

示例

HTML:

<div ng-controller="LogController">
  <!--这里不能用ng-bind,因为是渲染一段html文本,而不是显示简单的数据-->
  <div ng-bind-html="results"></div>
</div>

JS:

angular.module('myDemo', [])
  .controller('LogController', function ($scope, $http, $sce) {
  // 随便定义一段html文本
  var txt = "<h1>Hello world!</h1>";
  // 这里不能直接$scope.results = txt,否则会报错显示“不安全”
  $scope.results = $sce.trustAsHtml(txt);
  });

此时浏览器就会输出Hello world!

(完)

分类
JavaScript

AngularJS入门学习(三)控制器

controller是MVC(Model View Controller)框架中的一部分,(官方翻译)ngController指令是一个试图控制类,这是一个关键在angular如何支持模型视图控制器设计模式原则方面。Angular的控制器:ngController实际上是一个函数,指定一个Controller类,这个类控制业务逻辑和模型的在视图的绑定。

我们来看一段代码:

  <div ng-app="myapp" ng-controller="myCtrl">
    输入的姓名:<br/>
    名:<input type="text" ng-model="firstname"/><br/>
    姓:<input type="text" ng-model="lastname"/>
    <br />
    <h1>hello {{ firstname +" "+ lastname }}</h1>
  </div>
  <script>
    var app = angular.module("myapp" ,[]);
    app.controller('myCtrl', function($scope) {
      $scope.firstname = "John";
      $scope.lastname =  "Doe";
    });
  </script>

上面是一个最简单的使用ng-controller的实例

ng-controller="myCtrl" 属性是一个 AngularJS 指令。用于定义一个控制器。

myCtrl 函数是一个 JavaScript 函数。

AngularJS 使用$scope 对象来调用控制器。

控制器的 $scope (相当于作用域、控制范围)用来保存AngularJS Model(模型)的对象。

控制器在作用域中创建了两个属性 (firstName 和 lastName)。

ng-model 指令绑定输入域到控制器的属性(firstName 和 lastName)。

控制器也可以有方法

我们将上面的例子改变一下:

  <div ng-app="myapp" ng-controller="personCtrl">
    输入的姓名: <br/>
    名:
    <input type="text" ng-model="firstname" /><br/> 姓:
    <input type="text" ng-model="lastname" />
    <br /> 这里使用函数的方式输出的姓名
    <h1>hello {{ fullname() }}</h1>
  </div>
  <script>
    var app = angular.module("myapp", []);
    app.controller('personCtrl', function ($scope) {
      $scope.firstname = "John";
      $scope.lastname = "Doe";
      $scope.fullname = function () {
        return $scope.firstname + " " + $scope.lastname;
      }
    });
  </script>

这里我们使用调用函数的方式来输出姓名,将$scope.fullname绑定到HTML,这样修改input中的内容时,就可以看到全名被自动更新了。

分类
JavaScript

AngularJS入门学习(二)模型与作用域

一、AngularJS模型

  • AngularJSng-model指令可以将输入域的值与 AngularJS 创建的变量绑定。
  • ng-model的绑定是双向绑定,即在一方修改变量,另一方也会立即同步。

来看一个双向绑定的实例

<div ng-app="myapp" ng-controller="myCtrl">
  输入:<input ng-model="name"><br/>
  当前name值是:<p>{{ name }}</p>
</div>
<script>
  var app = angular.module('myapp',[]);
   app.controller('myCtrl',function($scope){
     // 将输入域的值与 AngularJS 创建的变量绑定
    $scope.name = 'John Doe';
});
</script>

Angular先是定义了name的值,并与input绑定,当你修改input的值时,Angular属性的值也会相应改变。

验证用户输入

来看一个实例,使用Angularjs自带的组件验证输入的邮箱地址是否合法

<form ng-app="" name="myForm">
  Email:
  <input type="email" name="myAddress" ng-model="text">
  <span ng-show="myForm.myAddress.$error.email">不是一个合法的邮箱地址</span>
</form>

以上实例中,提示信息会在 ng-show 属性返回 true 的情况下显示。

应用状态

ng-model 指令可以为应用数据提供状态值(invalid, dirty, touched, error):

<form ng-app="" name="myForm" ng-init="myText = 'test@runoob.com'">
  Email:
  <input type="email" name="myAddress" ng-model="myText" required></p>
  <h1>状态</h1>
  {{myForm.myAddress.$valid}}
  {{myForm.myAddress.$dirty}}
  {{myForm.myAddress.$touched}}
</form>

CSS 类

ng-model 指令基于它们的状态为 HTML 元素提供了 CSS 类:

<style>
  input.ng-invalid {
    background-color: lightblue;
  }
</style>
<body>
  <form ng-app="" name="myForm">
    输入你的名字:
    <input name="myAddress" ng-model="text" required>
  </form>

上面的实例,设置了input框未输入的背景颜色

ng-model 指令根据表单域的状态添加/移除以下类:(具体参考:AngularJS: API: form

  • ng-empty
  • ng-not-empty
  • ng-touched
  • ng-untouched
  • ng-valid
  • ng-invalid
  • ng-dirty
  • ng-pending
  • ng-pristine

二、AngularJS作用域

  • Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带。
  • Scope 是一个对象,有可用的方法和属性。
  • Scope 可应用在视图和控制器上。

如何使用 Scope

当你在 AngularJS 创建控制器时,你可以将 $scope 对象当作一个参数传递:

  <div ng-app="myApp" ng-controller="myCtrl">
    <h1>{{carname}}</h1>
  </div>
  <script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function ($scope) {
      $scope.carname = "Volvo";
    });
  </script>

当在控制器中添加 $scope 对象时,视图 (HTML) 可以获取了这些属性。

视图中,你不需要添加 $scope 前缀, 只需要添加属性名即可,如: {{carname}}。

Scope 概述

AngularJS 应用组成如下:

  • View(视图), 即 HTML。
  • Model(模型), 当前视图中可用的数据。
  • Controller(控制器), 即 JavaScript 函数,可以添加或修改属性。

scope 是模型。

scope 是一个 JavaScript 对象,带有属性和方法,这些属性和方法可以在视图和控制器中使用。

  <div ng-app="myApp" ng-controller="myCtrl">
    <input ng-model="name">
    <h1>{{greeting}}</h1>
    <button ng-click='sayHello()'>点我</button>
  </div>
  <script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function ($scope) {
      $scope.name = "Runoob";
      $scope.sayHello = function () {
        $scope.greeting = 'Hello ' + $scope.name + '!';
      };
    });
  </script>

Scope 作用范围

了解你当前使用的 scope 是非常重要的。

在以上两个实例中,只有一个作用域 scope,所以处理起来比较简单,但在大型项目中, HTML DOM 中有多个作用域,这时你就需要知道你使用的 scope 对应的作用域是哪一个。

  <div ng-app="myApp" ng-controller="myCtrl">
    <ul>
      <li ng-repeat="x in names">{{x}}</li>
    </ul>
  </div>
  <script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function ($scope) {
      $scope.names = ["Emil", "Tobias", "Linus"];
    });
  </script>

每个 <li> 元素可以访问当前的重复对象,这里对应的是一个字符串, 并使用变量 x 表示。

根作用域

所有的应用都有一个 $rootScope,它可以作用在 ng-app 指令包含的所有 HTML 元素中。

$rootScope 可作用于整个应用中。是各个 controller 中 scope 的桥梁。用 rootscope 定义的值,可以在各个 controller 中使用。

   <div ng-app="myApp" ng-controller="myCtrl">
    <h1>{{lastname}} 家族成员:</h1>
    <ul>
      <li ng-repeat="x in names">{{x}} {{lastname}}</li>
    </ul>
  </div>
  <script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function ($scope, $rootScope) {
      $scope.names = ["Emil", "Tobias", "Linus"];
      $rootScope.lastname = "Refsnes";
    });
  </script>