Node.js开发入门—Angular简单示例

在“使用AngularJS”中,我们提到了如何在Node.js项目中引入AngularJS,这次提供一个非常简单的示例,演示AngularJS里的指令数据绑定服务等内容。

我准备做Web后台管理系统,不同的管理员会有不同的权限,管理员登录后看到的菜单和他的权限有关,能看到什么,是动态生成的(类似RBAC)。本文的示例从这个项目而来,当然,现在还是最简单的。

如果没有特别说明,后面我们用到的示例都使用express generator生成。

Angular小demo

先搞起来吧。

第一步,进入myprojects目录,执行“express AngularDemo”。

第二步,导航到AngularDemo目录,执行“npm install”

第三步,到AngularJS下载最新的AngularJS库文件,我下载的是1.4.3 min版本,重命名为“angular-1.4.3.min.js”,放在AngularDemo/public/javascripts下面。对于我们这个简单的Demo,只要这一个文件就可以了。

第四步,准备我们要用的文件。

首先是admin.html,放在AngularDemo/public下面即可。admin.html的编码格式要用UTF8。内容如下:

<!DOCTYPE html>
<html ng-app="x-admin">
  <head>
    <meta charset="UTF-8">
    <title>X管理系统</title>
    <link rel="stylesheet" href="/stylesheets/admin.css">
  </head>
  <body>
    <div class="x-view-full" ng-controller="x-controller">
        <div class="x-project-header">
          <div id="x-project-title">X管理后台</div>
          <div id="x-login-user"><a href="/user/tttt">{{currentUser}}</a>&nbsp;<a href="/logout">退出</a></div>
        </div>
        <div class="x-sidemenu">
          <div class="x-sidemenu-one" ng-repeat="menu in menus" ng-show="menu.enabled">
            <p class="sidemenu-one">{{menu.text}}</p>
            <div class="x-sidemenu-two" ng-repeat="subMenu in menu.subMenus" ng-show="subMenu.enabled">
              <input type="button" class="sidemenu-button" value="{{subMenu.text}}" ng-click="setContent(subMenu.action)"></input>
            </div>
          </div>
        </div>
        <div class="x-contents">
          <div ng-include="content"></div>
        </div>
    </div>
    <script src="/javascripts/angular-1.4.3.min.js"></script>
    <script src="/javascripts/admin.js"></script>
  </body>
</html>

接着是admin.js文件,放在AngularDemo/public/javascripts下面。UTF8编码哦,内容如下:

angular.module(‘x-admin‘, []).
controller(‘x-controller‘, function ($scope, $http) {
  $scope.currentUser="ZhangSan";
  $scope.content = ‘/welcome.html‘;

  $scope.menus = [
    {
      text: "系统管理",
      enabled: true,
      subMenus:[
        {
          text: "用户管理",
          enabled: true,
          action:"/login.html"
        },
        {
          text: "角色管理",
          enabled: true,
          action:"/role"
        },
        {
          text: "权限管理",
          enabled: true,
          action:"/access"
        }
      ]
    },
    {
      text: "内容管理",
      enabled: true,
      subMenus:[
        {
          text: "直播监控",
          enabled: true,
          action:"/stream-monitor"
        },
        {
          text: "预约管理",
          enabled: true,
          action:"/book-mgr"
        }
      ]
    },
    {
      text: "推送管理",
      enabled: true,
      subMenus:[
        {
          text: "推送列表",
          enabled: true,
          action:"/push-list"
        },
        {
          text: "新增推送",
          enabled: true,
          action:"/add-push"
        }
      ]
    }
  ];  

  $scope.setContent = function(action){
    console.log(action);
    $scope.content=action;
  };
});

接下来我写了一个简单的CSS文件——admin.css,放在AngularDemo/public/stylesheets下面。内容如下:

a {
  color: #00B7FF;
}

div.x-view-full {
  width: 100%;
  height: 100%;
}

div.x-project-header {
  display: inline-block;
  position: absolute;
  border: 1px solid #E4E4E4;
  background: #F2F2F2;
  width: 100%;
  height: 60px;
  left: 0px;
  top: 0px;
}

div.x-sidemenu {
  display: inline-block;
  position: absolute;
  border: 1px solid #E4E4E4;
  background: #F2F2F2;
  left: 0px;
  top: 66px;
  width: 160px;
  height: 600px;
}

div.x-contents {
  display: inline-block;
  position: absolute;
  left: 170px;
  top: 66px;
  min-width: 200px;
  min-height: 200px;
}

div.x-sidemenu-one{
  margin-left: 8px;
}

div.x-sidemenu-two{
  margin-left: 14px;
  font-size: 14px;
}

p.sidemenu-one{
  font-size: 18px;
  font-weight: bold;
  color: black;
}

.sidemenu-button{
  font-size: 14px;
  border: 0px;
  margin-bottom: 6px;
  background: #F2F2F2;
}

.sidemenu-button:hover {background-color: #218fd5;}

#x-project-title{
  position: absolute;
  display: inline-block;
  top: 20px;
  left: 20px;
  font-size: 28px;
  font-weight: bold;
  width: 200px;
}

#x-login-user{
  position: absolute;
  display: inline-block;
  top: 30px;
  right: 10px;
  width: 200px;
  text-align: right;
}

div.admin-addUser{
  position: relative;
  top: 4px;
  left: 10px;
  width: auto;
  height: auto;
}

最后,为演示菜单功能,我们还需要welcome.html和login.html这两个静态的html文件,都放在public下面即可。

welcome.html内容如下:

Welcome to X-Manager!

login.html内容如下(注意,UTF8编码):

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>登录</title>
  </head>
  <body>
    <div class="form-container">
        <p class="form-header">登录</p>
        <form action=‘login‘ method=‘POST‘ align="center">
          <table>
            <tr>
                <td><label for="user">账号:</label></td>
                <td><input type="text" id="user" name="login_username" /></td>
            </tr>
            <tr>
                <td><label for="pwd">密码:</label></td>
                <td><input type="password" id="pwd" name="login_password" /></td>
            </tr>
            <tr>
              <td colspan=‘2‘ align="right">
                <a href="/signup">注册</a>
                <input type="submit" value=‘登录‘/>
              </td>
            </tr>
          </table>
        </form>
    </div>
  </body>
</html>

第五步,在AngularDemo目录里,执行“npm start”命令,启动网站。

第六步,在浏览器里访问“http://localhost:3000/admin.html”。应该会看到下面的效果哦:

创建基本AngularJS应用的步骤

前面我们不管三七二十一先把AngularDemo跑起来了。现在我们看下创建一个基本的AngularJS应用的步骤。

第一步是实现一个Node.js Web服务器。这个express为我们代劳了,我们就用默认的应用模板,你去看app.js的话,应该发现它把public目录使用app.static中间件处理了一下,我们可以直接在浏览器里访问public目录下的文件,比如http://localhost:3000/admin.html

第二步就是实现一个AngularJS HTML模板,比如我们的admin.html。这是最重要的,我们展开来看看。

1. 加载AngularJS库

嗯,script元素,放在HTML文档body元素的最后,如admin.html那样。浏览器会帮你下载并执行angular-1.4.3.min.js文件。HTML代码如下:

<script src="/javascripts/angular-1.4.3.min.js"></script>

2. 实现你的Angular模块

比如我们示例中的admin.js,它实现了一个控制器来支持HTML模板。

3. 加载你的主模块

script元素,就放在angular库的后面,放后面,这是必须的。HTML代码如下:

<script src="/javascripts/admin.js"></script>

4. 定义根元素

admin.html有这么一行代码:

<html ng-app="x-admin">

admin.js的第1行代码

angular.module(‘x-admin‘, [])

这两行代码是对应的,HTML里使用ng-app指令指定了Angular模块名字。而这个模块名字,就是你的js代码里使用angular.module定义模块时提供的第一个参数。对于我们的示例,模块名字叫“x-admin”。

在HTML中关联了ng-app后,就可以添加控制器了。

关于ng-app指令和angular.module方法,参考这里吧:http://docs.angularjs.cn/api。国内的,无需翻qiang。

使用angular.module定义模块时,第二个参数是依赖的模块列表,Angular会自动为你解决依赖注入问题。比如你依赖ui bootstrap,可以这么写:

angular.module(‘x-admin‘, [‘ui.bootstrap‘])

需要注意的是:文档里描述指令时,都是ngApp这种形式,而写代码时,是ng-app。angular的文档还是不错的,赞一个。

5. 添加控制器

admin.html文档中有这行代码:

<div class="x-view-full" ng-controller="x-controller">

上面的代码把名字是“x-controller”的控制器分配到

元素中,这样我们就可以在这个元素中使用js里定义的同名控制器的作用域内的数据(Model)。

admin.js的第2行代码:

controller(‘x-controller‘, function ($scope, $http) {

定义了一个控制器。具体的语法参考这里吧:http://docs.angularjs.cn/api。国内的,无需翻qiang。

controller是angular.Module的一个方法,用来定义控制器,原型是:

controller(name, constructor);

第一个参数是控制器的名字,第二个参数是控制器的构造函数。构造函数的参数是控制器依赖的服务。

还有一种语法controller(name,[]),第二个参数是控制器的依赖数组。比如:

controller(‘x-controller‘,[‘$scope‘, ‘$http‘, function($scope, $http){}]);

我看1.3.x,1.4.x的文档里controller方法的原型都是第一种,第二种是我在《Node.js+MongoDB+AngularJS Web开发》里看到。两种我都测试了,都可以用。但跟什么版本什么关系,存疑了。

6. 实现作用域模型

使用Module的controller方法定义控制器时,会让开发者提供控制器的构造函数。当Angular编译HTML时,会使用开发者提供的控制器构造函数创建控制器的实例。构造函数内,会初始化一些数据,关联到作用域scope上。在作用域scope里的数据和方法,都可以直接被HTML引用。

我在admin.js里x-controller控制器的构造函数内,提供了menus数组,用于构造管理界面的左侧菜单;提供了currentUser,显示在管理界面右上角;content则用来保存管理界面左下角区域使用的局部html模板;最后呢,提供了一个setContent方法,以便用户可以通过管理界面的菜单来更改content,进而改变功能区域的内容。

7. 在HTML模板中使用指令和绑定数据

其实在实现作用域模型时,心里对“什么数据和哪个HTML元素对应”这一点是一清二楚的,不清楚你也实现不来啊不是。

一旦你实现了作用域模型,就可以在HTML模板里使用ng指令来关联数据了。其实有时候你是先写HTML模板,还是先实现作用域模型,还真分不太清楚。

我们以admin.html为例来说明一下ng指令的用法,注意,只提admin.html中用到的,没用到就看http://docs.angularjs.cn/api。我们用到了ng-app、ng-controller、ng-repeat、ng-click、ng-show、ng-include、{{}}。

ng-appng-controller已经说过了。咱说没提过的。

<div id="x-login-user"><a href="/user/tttt">{{currentUser}}</a>&nbsp;<a href="/logout">退出</a></div>

这行代码里用到了{{expression}}这种语法,花括号之间是一个使用作用域内的变量构成的JS表达式。示例里直接引用了currentUser变量,实际运行中会用admin.js里的currentUser的值替换HTML文档中的这部分代码。如果在运行过程中currentUser变量的值发生变化,HTML也会变化,这是数据绑定。

我们可以修改一下admin.js,使用$interval服务来启动一个定时器,修改currentUser的值。新的admin.js是这样的:

angular.module(‘x-admin‘, []).
controller(‘x-controller‘, function ($scope, $http, $interval) {
  $scope.currentUser="ZhangSan";
  $scope.content = ‘/welcome.html‘;

  $scope.menus = [
    ......
  ];  

  $scope.setContent = function(action){
    console.log(action);
    $scope.content=action;
  };

  //2秒后改变一次currentUser
  $interval(function(){
    $scope.currentUser = "LiSi";
  }, 2000, 1);

});

ng-repeat指令可以根据一个集合,使用一个模板化的item来创建多个相似的HTML元素。

<div class="x-sidemenu-one" ng-repeat="menu in menus" ng-show="menu.enabled">

上面的代码使用ng-repeat指令,根据x-controller里定义的menus数组来创建多个

元素,每个

都具有相同的结构。在ng-repeat指令内,通常使用“x in collections”这种语法来遍历作用域中的某个集合,而x又可以在ng-repeat定义的模板元素内部使用。比如上面定义的div模板,使用ng-show指令时就使用了“menu in menus”中定义的menu变量。同时这个div模板内部代码也引用了menu,参看下面的代码:

<p class="sidemenu-one">{{menu.text}}</p>

ng-show指令放在某个HTML元素内部,用来指示是否显示该元素。

ng-click指令可以指定某个元素被点击时的响应(函数)。

<input type="button" class="sidemenu-button" value="{{subMenu.text}}" ng-click="setContent(subMenu.action)">

上面的代码使用ng-click指令为代表子菜单的按钮指定了响应鼠标点击的代码“setContent(subMenu.action)”。setContent是作用域内定义的方法,subMenu是ng-repeat指令内定义的变量。

有了这样的处理,当用户点击某个菜单时,就会调用到admin.js里的setContent方法来改变content的值。而这种改变,会反过来影响HTML的效果,改变管理页面左下区域内显示的内容。示例里当你点击用户管理时会显示一个登陆页面。

促成这种效果的代码如下:

<div ng-include="content"></div>

上面的代码使用ng-include指令来包含一个HTML片段。当你使用ng-include指定了一个html片段后,Angular会解析这个指令,获取对应的html文档,编译,并且将其内容整合进原始html文档内。



其它文章:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-24 02:51:51

Node.js开发入门—Angular简单示例的相关文章

Node.js开发入门—语音合成示例

出于项目需要,搞了一个语音合成(TTS)的小示例,使用的是OKVoice. 我想在PC上测试,OKVoice的快速接入API可以实现我的目的,文档在这里:http://dev.okvoice.com/file.php. 直接上代码吧,okVoiceTts.js,内容如下: var http = require('http'); var fs =require('fs'); var crypto = require('crypto'); var util = require('util'); va

Node.js开发入门—使用对话框ngDialog

做网站经常会遇到弹出对话框获取用户输入或弹出对话框让用户确认某个操作之类的情景,有一个基于AngularJS的扩展模块可以帮我们优雅地完成这类事情:ngDialog. ngDialog在github上提供了一个示例网页,演示了它的各种用法,在这里:https://github.com/likeastore/ngDialog/blob/master/example/index.html.ngDialog的github主页的readme也对常用的指令和服务做了较为详细的介绍,可以参考.我这篇就纯粹是

Node.js开发入门—Stream用法详解

Stream是Node.js中非常重要的一个模块,应用广泛.一个流是一个具备了可读.可写或既可读又可写能力的接口,通过这些接口,我们可以和磁盘文件.套接字.HTTP请求来交互,实现数据从一个地方流动到另一个地方的功能. 所有的流都实现了EventEmitter的接口,具备事件能力,通过发射事件来反馈流的状态.比如有错误发生时会发射"error"事件,有数据可被读取时发射"data"事件.这样我们就可以注册监听器来处理某个事件,达到我们的目的. Node.js定义了R

Node.js开发入门—UDP编程

Node.js也提供了UDP编程的能力,相关类库在"dgram"模块里. 与TCP不同,UDP是无连接的,不保障数据的可靠性,不过它的编程更为简单,有时候我们也需要它.比如做APP的统计或者日志或者流媒体,很多流媒体协议都会用到UDP,网上一搜一大堆. 使用UDP,如果你要发送数据,只需要知道对方的主机名(地址)和端口号,扔一消息过去即可.至于对方收不收得到,听天由命了.这就是数据报服务,类似快递或邮件. 我们这次来介绍一下Node.js里的UDP编程,我会提供一个UDP版本的echo

Node.js开发入门—使用http访问外部世界

Node.js的http模块,不但可以构建服务器,也可以作为客户端类库来访问别的服务器.关键就在两个方法: http.request(options[,callback]) http.get(path[,callback]) 除了http,还会用到FileSystem模块和Stream中的stream.Readable和stream.Writable. 先来大概介绍一下相关API吧. API解释 http.request()方法接受一个options参数,这个参数可以是对象,用来指明你要访问的网

Node.js开发入门—套接字(socket)编程

Node.js的net模块提供了socket编程接口,方便我们利用较为底层的套接字接口来实现应用协议.这次我们看一个简单的回显服务器示例,包括服务端和客户端的代码. 使用JavaScript也可以进行套接字编程,哈哈,这酸爽! 代码 分服务器和客户端两部分来说吧. echoServer代码分析 echoServer.js: var net = require("net"); // server is an instance of net.Server // sock is an ins

Node.js开发入门—notepad++ for Node.js

对于Node.js开发,论IDE的话,Webstorm是不二的选择,但它是收费的(可免费使用30天).一开始,我们先将就一下,使用notepad++来编写Node.js应用.这样做还有一大好处:没有关于Node.js的代码高亮和自动补全,可以更好地敦促我们使用在线API文档记忆各种类库API.死磕自己吧,enjoy it. notepad++的安装与配置 到"https://notepad-plus-plus.org/download/v6.8.2.html"这里下载吧,6.8.2版本

Node.js开发入门—使用AngularJS内置服务

在上一篇,"AngularJS简单示例"中演示了一个非常简单的使用Angular的小demo,那篇已经太长,原本要介绍的一些内容只好单另开篇了.这些内容,就是如何使用Angular服务. 我们还是基于"AngularJS简单示例"中的示例来改造一下.新的示例,能从Node.js+Express构造的服务器上获取管理菜单.为了实现这个,需要做几部分改造: 服务器提供adminMenu的下载功能,需要修改app.js,处理路由 修改Angular实现的控制器x-cont

Node.js开发入门——MongoDB与Mongoose

为了保存网站的用户数据和业务数据,通常需要一个数据库.MongoDB和Node.js特别般配,因为MongoDB是基于文档的非关系型数据库,文档是按BSON(JSON的轻量化二进制格式)存储的,增删改查等管理数据库的命令和JavaScript语法很像.如果你在Node.js里访问MongoDB的数据,会有我们是一家人的感觉,特别亲切. 我也准备使用MongoDB来作为我的数据库. MongoDB使用集合(collection)和文档(document)来描述和存储数据,collection就相当