compound controller介绍

说明:本文是按照compound官网文档,学习总结翻译而来。

1.      使用命令创建一个项目。

$compound init 项目名称

2.      在开发模式下,我们修改model  controller  view 等它都会自动更新,但是修改routes 或者 scheme我们就必须重启服务。或者可以使用node-dev命令(npm install node-dev first),在每次修改后都会自动重启服务。

3.      使用compoundroutes 可以查看所有提供给应用程序的有效路由

 

4.      Compoundjs有两种控制器。

(1)      evalController(文件名以_controller结尾):这种控制器提供方便的接口,以较少的代码完成表示。但是它调试困难,缺少常见的特性例如继承,meta-programming(不知该如何翻译)

Example of evalcontroller: app/controllers/car_controller.js:

load('essentials');// load parent controller
before(functionthink() {
    // think for 1 second before acceperate
    setTimeout(function() {
        next();
    });
}, {only:'accelerate'});
action('accelerate',function() {
    send(++this.speed);
});
action('brake',function() {
    send(--this.speed);
});


(2) noevalcontroller(文件不是以_controller结尾)方便调试,支持继承,meta-programming

Example of noevalcontroller: app/controllers/car.js:


module.exports =CarController;
// load parentcontroller
var Essentials =require('./essentials');
 
functionCarController(init) {
    // call parent constructor
   Essentials.call(this, init);
    init.before(function think(c) {
        // think for 1 second before accelerate
        setTimeout(function() {
            c.next();
        });
    }, {only: 'accelerate'});
}
// setupinheritance
require('util').inherits(CarController,Essentials);
 
CarController.prototype.accelerate= function(c) {
    c.send(++this.speed);
};
 
CarController.prototype.brake= function(c) {
    c.send(++this.speed);
};


 说明:二者主要的区别在于:使用控制器的上下文(环境)。

(1)       如果是eval,它可能仅仅是调用控制器环境成员作为全局变量:next,req,res,send,render或者其它。而            noeval,每一个action或者hook接收上下文(环境)对象作为第一个参数,所有的环境特性适应于这个对象。

(2)       使用eval调用action(name,fn)方法。第一个参数是可选的。调用hook使用before,after方法。使用noeval。Controller file 应该export 构造方法。Actions 作为构造函数的原型方法。控制器构造函数接收init对象。它可以识别当前的控制器。定义hook调用init对象上的before和after方法,传递给构造函数。

(3)       控制器上下文环境有以下成员:req,  res,  body(如果是get方法它是空。)

(上面三个是控制器成员,接下来是一些控制器方法。)

 

5.      output 方法(每一个action都要有一个输出方法。)控制器output方法。

(1)      render(); 接收0,1,或者2个参数。第一个参数读取哪个一个view.如果要给view传递变量,可以使用.render({title:’Hello’});

eg:  

PostsController.prototype.update = function update(c) {
    this.title = 'Edit post';
    c.render('edit');
};


(2)      send(smth):给客户端发送text,状态码,json对象等。它在调试的时候非常有用,或者是你不想给一个页面读取沉重的模板,仅是想发送文本,json对象。

Eg:

 c.send(403);   c.send(‘hello’);     c.send({hello:’world’});

(3)      redirect(location):仅需设置状态码和locationheader。客户端就可以跳转到另外一个location.

Eg:  

 redirect(‘/’);      //路由跳转

 redirect(‘http://example.com’);    //跳转到另外一个host

(4)      header()   为客户端设置header

(5)      flash(type,message):  显示flash信息。Flash函数在session中存储信息,使之稍后显示。

Eg: 

PostsController.prototype.create = functioncreate(c) {
   c.Post.create(req.body, function (err) {
       if (err) {
           c.flash('error', 'Error while post creation');
           c.render('new', {post: req.body});
       } else {
           c.flash('info', 'Post has been successfully created');
           c.redirect(c.pathTo.posts);
       }
   });
});


6.      控制器流控制方法。

(1)      before([name,]hook[,params]):  在任何action前面使用hook,name参数是可选的当hook是有名函数。

Eg1

{ only:['actionName', 'actionName2'] }
{ except:'anotherActionName' }


     说明:第一个配置将运行hook,only 为actionName  actionName2  action。第二个配置将在每一个action之前运行hook 除了 'anotherActionName'。

Eg2:

Fragmentof app/controllers/checkout.js:


function CheckoutController(init) {
   init.before(userRequired, { only: 'order' });
   init.before(prepareBasket, { except: 'order' });
   init.before(loadProducts, { only: ['products', 'featuredProducts'] });
}
 
CheckoutController.prototype.products =function(c) { ... };
CheckoutController.prototype.featuredProducts= function(c) { ... };
CheckoutController.prototype.order =function(c) { ... };
CheckoutController.prototype.basket =function(c) { ... };
 
function userRequired(c) { c.next() }
function prepareBasket(c) { c.next() }
function loadProducts(c) { c.next() }


注意:

(1)before方法应当调用全局 next()方法,这样就可以将控制传递给调用链条中的下一个方法。

(2)      after([name,]hool[,params])  在action后面调用方法。

(3)      skipBefore(name,params)

(4)      skipAfter(name,params)

(5)      next(err)

7.      仅在eval中的方法。

(1)      eval有一些方法允许控制器之间共享代码。(noeval)不需要这个,因为它可以使用require和继承

(2)      load: 加载另一个控制器,使用它其中的方法。

(3)      use: 得到另一个控制器中已经定义的方法,在使用load加载之后。

(4)      publish:允许方法被其他控制器使用。

Eg:

Fragment of app/controllers/application_controller.js:

publish('requireUser', requireUser);
 
function requireUser () {
   // ...
}
Fragmentof app/controllers/products_controller.js:
load('application'); // note that_controller siffix omitted
before(use('userRequired'), { only: 'products'});


8.      扩展控制器上下文环境,使用compound.controllerExtensions对象。这个对象的方法将混合在每一个控制器上下文环境。

Eg:

compound.controllerExtensions.socketSend =function(arg) {
   socketIO.send(arg);
};
Then it will be possible tocall socket('hello') in eval controller, andc.socket('hello') innoeval controller.

9.      view

lists_controller.js中index action下,使用render(); 则默认调用的view是:

./app/views/lists/index.ejs

10.  layout

(1)如果render aview 不带有layout 我们可以使用{layout:false}作为render()的参数开设置,也可以使用$this->layout = false;在controller中设置。

(2)如果使用layout可以用c.layout(‘’);指定想要用的layout

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值