0

Phil Sturgeon によって書かれた rest ライブラリを使い始めたところです。簡単な例をいくつか書くことから始めました。get 'post' と 'get' の作業は不足していますが、put と delete は不足しています。以下のコードに基づいていくつか質問があります。

// a simple backbone model
var User = Backbone.Model.extend({
    urlRoot: '/user',
    defaults:{
        'name':'John',
        'age': 17
    }
});

var user1 = new User();
//user1.save(); // request method will be post unless the id attr is specified(put)
//user1.fetch(); // request method will be get unless the id attr is specified
//user1.destroy(); // request method will be Delete with id attr specified

私のCI RESTコントローラーで

class User extends REST_Controller
{
    public function index_get()
    {
        echo $this->get(null); //I can see the response data
    }

    public function index_post()
    {
        echo $this->post(null); //I can see the response data
    }

    public function index_put()
    {

    }

    public function index_delete()
    {

    }
}

基本的に、コントローラーの get と post は、モデルを保存またはフェッチするときに呼び出されます。モデルで指定された ID を使用して、model.save() と model.destroy() を使用して、サーバーに対して put または delete 要求を行うことができます。しかし、サーバーエラーが発生しました。index_put または index_delete を呼び出せないようです。誰も私がどのように対処できるか知っていますか:

  1. コントローラーにリクエストを入れる
  2. コントローラーの削除リクエスト
  3. ID を指定して単一のレコードを取得する

git から、私は彼が index_post と index_put をリストするのを見ただけでした。index_put と index_delete のデモはありません。誰かが私を助けることができますか?ありがとう

4

1 に答える 1

2

私はまったく同じ問題に直面しました.DELETE、PUT、PATCHメソッドはまだbrowser/html/serverで完全にサポートされていないようです. 次のスタック オーバーフローの質問を参照してください。PUT、DELETE、HEAD などのメソッドは、ほとんどの Web ブラウザーで使用できますか?

簡単な解決策はmethodMap、バックボーン ライン 1191 を次のように変更することです。

 // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
 var methodMap = {
  'create': 'POST',
  'update': 'POST',     //'PUT',
  'patch':  'POST',     //'PATCH',
  'delete': 'POST',     //'DELETE',
  'read':   'GET'
 };

次に、モデルの属性としてアクション タイプを含めます。

 var Person = Backbone.Model.extend({
      defaults:{
         action_type : null,
         /*
          * rest of the attributes goes here
          */
      },
      url : 'index.php/person'
 });

モデルを保存する場合は、次のようにします。

 var person = new Person({ action_type: 'create' });
 person.set( attribute , value );  // do this for all attributes
 person.save();

フォルダーには、 REST_Controller を拡張する Person という名前のクラスでapplication/controllers呼び出されるコントローラーが必要ですperson.php。これには、次のメソッドがあります。

class Person extends REST_Controller {

   function index_get()  { /* this method will be invoked by read action */  }

   /*  the reason those methods are prefixed with underscore is to make them
    *  private, not invokable by code ignitor router. Also, because delete is
    *  might be a reserved word
    */

   function _create()  { /* insert new record */  }
   function _update()  { /* update existing record */  }
   function _delete()  { /* delete this record */  }
   function _patch ()  { /* patch this record */  }

   function index_post() {

      $action_type = $this->post('action_type');
      switch($action_type){

           case 'create' : $this->_create();  break;
           case 'update' : $this->_update();  break;
           case 'delete' : $this->_delete();  break;
           case 'patch'  : $this->_patch();   break;
           default:
               $this->response( array( 'Action '. $action_type .' not Found' , 404) );
               break;

      }
   }
}

そうは言っても、この解決策は醜いものです。バックボーンの実装を上にスクロールすると、1160 行目に次のコードが見つかります。

// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
    params.type = 'POST';

つまり、バックボーン構成のエミュレート オプションを設定する必要があります。次の行をmain.js

 Backbone.emulateHTTP = true;
 Backbone.emulateJSON = true;

その効果をテストするために、単純なモデルを作成しました。結果は次のとおりです。

applications/controllersという名前のファイルに、フォルダー内のApi というコントローラーが必要です。api.php

<?php defined('BASEPATH') OR exit('No direct script access allowed');

require_once APPPATH.'/libraries/REST_Controller.php';

class Api extends REST_Controller
{

   function index_get()
   {
    $this->response(array("GET is invoked"));
   }

   function index_put()
   {
    $this->response(array("PUT is invoked"));
   }

   function index_post()
   {
    $this->response(array("POST is invoked"));
   }

   function index_patch()
   {
    $this->response(array("PATCH is invoked"));
   }

   function index_delete()
   {
    $this->response(array("DELETE is invoked"));
   }

}

js/modelsフォルダーに、というモデルを作成しますapi_model.js

var Api = Backbone.Model.extend({
       defaults:{ 
            id:      null, 
            name:    null
       },
       url: "index.php/api/"
});

var api = new Api();

api.fetch({ success: function(r,s) { console.log(s); } });  // GET is invoked

api.save({},{ success: function(r,s) { console.log(s); } }); // POST is invoked

//to make the record old ( api.isNew() = false now )
api.save({id:1},{ success: function(r,s) { console.log(s); } }); // PUT is invoked

api.destroy({ success: function(r,s) { console.log(s); } }); //DELETE is invoked

パッチのやり方がわかりませんが、参考になれば幸いです。

編集

コードイグナイターのREST実装に含まれていないパッチのやり方を知りました。REST_Controller の 39 行目に、次の内容があります。

protected $allowed_http_methods = array('get', 'delete', 'post', 'put');

'patch'このメソッドを受け入れるには、最後に追加する必要があります。また、それを行った後、このコードを追加します

/**
 * The arguments for the PATCH request method
 *
 * @var array
 */ 
protected $_patch_args = array();

また、次のコードを追加して、パッチ引数を解析する必要があります。

/**
 * Parse PATCH
 */
protected function _parse_patch()
{
    // It might be a HTTP body
    if ($this->request->format)
    {
        $this->request->body = file_get_contents('php://input');
    }

    // If no file type is provided, this is probably just arguments
    else
    {
        parse_str(file_get_contents('php://input'), $this->_patch_args);
    }
}

バックボーンのドキュメントによると{patch: true}、PATCH メソッドを送信するために渡す必要があります。次の行を呼び出すと、パッチが実行されます。

 api.save({age:20},{patch: true, success: function(r,s) { console.log(s); } });

 // PATCH is invoked
于 2013-06-05T12:25:37.847 に答える