2011-08-02 8 views
12

POCOとknockoutjsの間でマッピングする方法はありますか?knockoutjsからPOCOオブジェクトへのマッピング/

は私が注意クラスがあります。

public class Note 
{ 
    public int ID { get; set; } 
    public string Date { get; set; } 
    public string Content { get; set; } 
    public string Category { get; set; } 
    public string Background { get; set; } 
    public string Color { get; set; } 
} 

をし、これが私のjavascriptです:

$(function() { 
    ko.applyBindings(new viewModel()); 
}); 

function note(date, content, category, color, background) { 
    this.date = date; 
    this.content = content; 
    this.category = category; 
    this.color = color; 
    this.background = background; 
} 

function viewModel() { 
    this.notes = ko.observableArray([]); 
    this.newNoteContent = ko.observable(); 

    this.save = function (note) { 
     $.ajax({ 
       url: '@Url.Action("AddNote")', 
       data: ko.toJSON({ nota: note }), 
       type: "post", 
       contentType: "json", 
       success: function(result) { } 

      }); 
    } 

    var self = this; 
    $.ajax({ 
     url: '@Url.Action("GetNotes")', 
     type: "get", 
     contentType: "json", 
     async: false, 
     success: function (data) { 
      var mappedNotes = $.map(data, function (item) { 
       return new note(item.Date, item.Content, item.Category, item.Color, item.Background); 
      }); 
      self.notes(mappedNotes); 
     } 
    }); 
} 

が使用されていない機能を保存する(ここでは、コードを簡素化する)という事実を無視します。

私はページをロードするときにサーバーを呼び出し、ノートオブジェクトのリストを取得し、JavaScriptでマップします。 IDがマップされていないことに注意してください。

これまでのところ、画面上にメモが表示されていましたが、メモをサーバーに保存する方法はありますか?

私はメモを(JSONに新しいメモだけで、コレクション全体ではなく)保存して、それを私のコントローラに送信しようとしましたが、コントローラのメモへのアクセス方法はわかりません。私は試しました:

public string AddNote(string date, string content, string category, string background, string color) 
    { 
     // TODO 
    } 

しかし、動作していません。私はこれを行う方法、だから、

public string AddNote(Note note) {} 

(ところで、ちょうどDBにデータを保存する方法のための最高のリターンは何無効?)

:私のような何かをしたいですか?私はknockout.mappingプラグインを試しましたが、それはかなり混乱していて、私はそれを私のために働かせません。

ありがとうございます。

答えて

24

ASP.NET MVCのモデルバインダーは、大文字と小文字を区別するプロパティを検索します。あなたのpocoオブジェクトに一致するプロパティ名を持つJSONオブジェクトをサーバーに戻す必要があります。

は、私は通常1〜2のものの操作を行います。(私は、このオブジェクトはいくつかの点で、サーバ用にDTOになることを知って、JSでそのように)私のjavascriptオブジェクトのプロパティ名資本を作る

  1. 私のAJAX呼び出しで
    function Note(date, content, category, color, background) { 
        this.Date = date; 
        this.Content = content; 
        this.Category = category; 
        this.Color = color; 
        this.Background = background; 
    }; 
    
  2. 私は(これはko.toJSONを必要としませんのでご注意)バックサーバに渡すために匿名のオブジェクトを作成します。

    $.ajax({ 
         url: '@Url.Action("AddNote")', 
         data: JSON.stringify({ note: { 
           Date: note.date, 
           Content: note.content, 
           Category: note.category, 
           Color: note.color, 
           Background: note.background 
           } 
          }), 
         type: "post", 
         contentType: "application/json; charset=utf-8", 
         success: function(result) { } 
    }); 
    

    (同様に異なるのcontentTypeパラメータに注意してください)

あなたのActionMethodは、パラメータの配列だけ(Note note)に取るとないようにしたいでしょう。

また、モデルバインダーは、いくつかの異なる方法で投稿された値を調べます。ただやる

{ note: { 
     Date: note.date, 
     Content: note.content, 
     Category: note.category, 
     Color: note.color, 
     Background: note.background 
     } 
    } 

{ 
     Date: note.date, 
     Content: note.content, 
     Category: note.category, 
     Color: note.color, 
     Background: note.background 
    } 

(しかし、これが配列のコレクションと複合体に結合してdicey得ることができるのではなく、 :私は運アウトがActionMethodパラメータ名を指定してJSONオブジェクトを掲示しなければなりませんでした型...など)

dbコールを行うメソッドの返り値として「ベスト」シグネチャと同様に、我々は一般的にブール値を見ることを好みますが、それはまた必要に応じて異なります。明らかにそれが些細なデータであれば、voidは問題ありませんが、少し重大であれば、(少なくとも並行処理の例外がある場合は)リトライする必要があることをクライアントに知らせるために、 。

データベースに何が起こったかをクライアントに知らせる必要がある場合は、custom error handlingexception catchingの世界に進出することができます。

データベースコミットの成功/失敗に応じて、特定の情報をユーザーに表示する必要がある場合は、custom ActionResultsを作成すると、データベーストランザクションで発生した内容に基づいて特定のビューにリダイレクトされます。までさかのぼるサーバーからデータを取得し、ノックアウトを使用するなど、

最後に、...

  1. あなたのプロパティ名が同じ場合であるか、あなたはもう少し明示的なマッピング
  2. を作成する場合は、再度マッピング・プラグインが動作します
  3. 自分のJSオブジェクトで自分のトリックは以下のとおりです。初期化関数は、プロパティ名が(小文字になった後に)一致するか、関数(ノックアウト対応)を呼び出すことによってそれらを設定するか、単に値を代入すると、すべてのオブジェクトにわたって再利用できるように作成されたものです。:

    function Note(values){ //values are what just came back from the server 
        this.date; 
        this.content; 
        this.category; 
        this.color; 
        this.background; 
    
        initialize(values); //call the prototyped function at the bottom of the constructor 
    }; 
    
    Note.prototype.initialize = function(values){ 
        var entity = this; //so we don't get confused 
         var prop = ''; 
         if (values) { 
          for (prop in values) { 
           if (values.hasOwnProperty(prop.toLowerCase()) && entity.hasOwnProperty(prop.toLowerCase())) { 
            //the setter should have the same name as the property on the values object 
    
            if (typeof (entity[prop]) === 'function') { 
             entity[prop](values[prop]); // we are assuming that the setter only takes one param like a Knockout observable() 
            } else {// if its not a function, then we will just set the value and overwrite whatever it was previously 
             entity[prop] = values[prop]; 
            } 
           } 
          } 
         } 
    }; 
    
+1

叙事詩答え恐ろしいこれは完璧に動作しますが、:あなたは私の最後の段落を説明することができ...どのサーバからロードするように手動マッピングをImはここでやってか、私は、マッピング・プラグインを試してみて??? –

+1

はい、偉大な答えは+1です。これは非常に明確な例です。 –

+0

うわー、すばらしい仕事。 –

関連する問題