2016-08-09 47 views
0

Ich habe Probleme mit dem Binding-Modell nach dem Erstellen einer Aktion mit Kendo UI mit Angular.Wie binden Sie ein Modell in Kendo UI?

Nach Anfrage erstellen im Debug-Modus habe ich erfolgreich benötigt Aktion Aufruf in PoController, aber das Objekt, das Controller akzeptieren muss, ist leer.

In Fiedler I Anfrage mit Körper beobachten kann '/ PO/Erstellen':

Modelle =% 5B% 7B% 22id% 22% 3Anull% 2C% 22po_number% 22% 3A% 221% 22% 2C% 22note% 22% 3A% 22ojklj% 22% 2C% 22valid_start% 22% 3A% 222016-08-09T10% 3A06% 3A46.703Z% 22% 2C% 22valid_end% 22% 3A% 222016-08-09T10% 3A06% 3A46.703Z% 22% 7D% 5D

Kann jemand mit Modellbindung helfen? Kann Kendo UI Datenquelle falsch konfiguriert sein?

app.js

var app = angular.module("app", ["kendo.directives"]); 

poDataSource.js

'use strict'; 

app.factory('poDataSource', 
    function() { 
     return new kendo.data.DataSource({ 
      transport: { 
       type: "odata", 
       read: { 
        url: '/PO/GetAll', 
        datatype: 'jsonnp', 
        type: 'get', 
       }, 
       create: { 
        url: "/PO/Create", 
        dataType: "jsonp", 
        type: "post" 
        }, 
       parameterMap: function (options, operation) { 
         if (operation !== "read" && options.models) { 
          return { models: kendo.stringify(options.models) }; 
         } 
        } 
       }, 
       batch: true, 
       pageSize: 5, 
       schema: { 
        model: { 
         id: "id", 
         fields: { 
          id: { editable: false, nullable: true }, 
          po_number: { type: "string" }, 
          note: { type: "string" }, 
          valid_start: { type: "date" }, 
          valid_end: { type: "date" } 
         } 
        } 
       } 

      }); 
    }); 

Index.cshtml

<kendo-grid k-data-source="dataSource" 
      k-columns="gridColumns" 
      k-editable="'inline'" 
      k-toolbar="['create']" 
      k-sortable="true" 
      k-pageable="true" 
      k-resizeable="true"> 
</kendo-grid> 

_Layout.cshtml

<!DOCTYPE html> 
<html> 
<head> 
    <title>@ViewBag.Title - SWE Team Dashboard</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/kendo/2016.1.226/kendo.common-material.min.css")" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/kendo/2016.1.226/kendo.mobile.all.min.css")" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/kendo/2016.1.226/kendo.dataviz.min.css")" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/kendo/2016.1.226/kendo.material.min.css")" rel="stylesheet" type="text/css" /> 
    <link href="@Url.Content("~/Content/kendo/2016.1.226/kendo.dataviz.material.min.css")" rel="stylesheet" type="text/css" /> 
    <script src="@Url.Content("~/Scripts/kendo/2016.1.226/jquery.min.js")"></script> 
    <script src="@Url.Content("~/Scripts/kendo/2016.1.226/angular.min.js")"></script> 
    <script src="@Url.Content("~/Scripts/kendo/2016.1.226/jszip.min.js")"></script> 
    <script src="@Url.Content("~/Scripts/kendo/2016.1.226/kendo.all.min.js")"></script> 
    <script src="~/Content/app/app.js"></script> 
    <script src="~/Content/app/services/appService.js"></script> 
    <script src="~/Content/app/services/poDataSource.js"></script> 
    <script src="~/Content/app/controllers/homeController.js"></script> 
</head> 
<body ng-app="app" ng-controller="homeController as app"> 
    <header> 
     <div class="content-wrapper"> 
      <div class="float-left"> 
       <p class="site-title">@Html.ActionLink("SWE Team Dashboard", "Index", "Home")</p> 
      </div> 
      <div class="float-right"> 
       <nav> 
        <ul id="menu"> 
         <li>@Html.ActionLink("PO", "Index", "Home")</li> 
         <li>@Html.ActionLink("TMT Tasks", "Tasks", "Home")</li> 
         <li>@Html.ActionLink("Task to PO mapping", "TaskPOReferences", "Home")</li> 
        </ul> 
       </nav> 
      </div> 
     </div> 
    </header> 
    <div id="body"> 
     @RenderSection("featured", required: false) 
     <section class="content-wrapper main-content clear-fix"> 
      @RenderBody() 
     </section> 
    </div> 

    <footer> 
     <div class="content-wrapper"> 
      <div class="float-left"> 
       <p>&copy; @DateTime.Now.Year - My Telerik MVC Application</p> 
      </div> 
     </div> 
    </footer> 
</body> 
</html> 

POController.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using Dashy.DB.Model; 
using Dashy.Models; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
using System.Threading.Tasks; 

namespace Dashy.Controllers 
{ 
    public class POController : Controller 
    { 
     // GET: PO/GetAll 
     public async Task<ActionResult> GetAll() 
     { 
      var allItems = new PODAL().GetAll(); 

      return Json(allItems, JsonRequestBehavior.AllowGet); 
     } 

     public ActionResult Create() 
     { 
      return View(); 
     } 

     [HttpPost] 
     public ActionResult Create(PO po) 
     { 
      try 
      { 
       new PODAL().AddPo(po); 
       return RedirectToAction("Index"); 
      } 
      catch (Exception exception) 
      { 
       return View(); 
      } 
     } 




     // GET: PO/GetTaskToPoMapping 
     public string GetTaskToPoMapping() 
     { 
      var allItems = new PODAL().GetTaskToPoMapping(); 
      var jsonResult = JsonConvert.SerializeObject(allItems, 
       new JsonSerializerSettings() 
       { 
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore 
       }); 
      return jsonResult; 
     } 
    } 
} 

PO.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using NHibernate; 

namespace Dashy.DB.Model 
{ 
    public class PO 
    { 
     public virtual string note { get; set; } 
     public virtual int id { get; set; } 
     public virtual DateTime valid_start { get; set; } 
     public virtual DateTime valid_end { get; set; } 
     public virtual string po_number { get; set; } 
     public virtual IList<POLine> po_lines { get; set; } 

     public virtual void AddPOLine(POLine line) 
     { 
      line.po = this; 
      po_lines.Add(line); 
     } 
     public PO() 
     { 
      po_lines = new List<POLine>(); 
     } 
    } 
} 
+0

Ich hatte gerade ein Problem, Variable ID ist deklarieren als int, aber Sie senden NULL-Wert im Modell machen es Nullable oder ändern Sie die Modelldaten 'models = [{" id ": null," po_number ": "1", "Anmerkung": "ojklj", "valid_start": "2016-08-09T10: 06: 46.703Z", "valid_end": "2016-08-09T10: 06: 46.703Z"}] ' – Vijai

+0

@ Vijai Ist es nicht gemeint, dass id NULL ist: id: {editierbar: false, nullable: true}? Oder meinst du etwas anderes? –

+0

@StanislavMachel, '" [{"id": null, "po_number": "1", "Anmerkung": "ojklj", "valid_start": "2016-08-09T10: 06: 46.703Z", "valid_end" : "2016-08-09T10: 06: 46.703Z"}] "' Sie senden eine Liste an den Server, aber in POST Create Action kann ich die PO von thare sehen, also sollte es 'List ' oder Ihr Client-Code sein muss geändert werden. BTW, Sie können auch etwas namens 'DatasourceRequest' in Argumenten setzen –

Antwort

0

Vorherige Antworten hilft mir richtig desicion dieser Ausgabe zu erhalten. Wenn batch als true festgelegt wird, gibt es eine Liste von Elementen zurück, dh ich muss meinen Controller, den er empfangen kann, erneut implementieren List<PO>.

Aber hier ist auch ein anderes großes Problem. In der Tat gibt dieser Controller keine HTTP-Antwort zurück, aber Return View und bessere Entscheidung ist WEB API implementieren. Bassicaly musste ich Programm neu implementieren.

Hier einige Änderungen

POController.cs

using Dashy.DB.Model; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Web.Http; 
using Dashy.Models; 
using System.ComponentModel.DataAnnotations; 
using FluentNHibernate.Conventions.Inspections; 
using System.Web.Mvc; 

namespace Dashy.Controllers 
{ 
    public class TestController : ApiController 
    { 
     private PODAL _podal = new PODAL(); 

     public IQueryable<PO> GetPOs() 
     { 
      return _podal.GetAll().AsQueryable(); 
     } 

     public HttpResponseMessage PostPO([Bind(Exclude="id,po_lines")]PO po) 
     { 
      po.po_lines = new List<POLine>(); 

      if (ModelState.IsValid) 
      { 
       _podal.AddPo(po); 
       HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, po); 
       response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = po.id })); 
       return response; 
      } 
      else 
      { 
       return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); 
      } 
     } 
} 

poDataSource.js

'use strict'; 

app.factory('poDataSource', 
    function() { 
     return new kendo.data.DataSource({ 

      transport: { 
        type: "odata", 
        read: { 
         url: '/api/po', 
         type: 'get', 
        }, 
        update: { 
         url: '/api/po', 
         dataType: "json", 
         type: "PUT", 
         contentType: "application/json" 
        }, 
        create: { 
         url: "/api/po", 
         dataType: "json", 
         type: "POST", 
         contentType: "application/json" 
        }, 
        parameterMap: function (options, operation) { 
          if (operation !== "read") { 
           debugger; 
           return JSON.stringify(options); 

         } 
        } 
       }, 
       pageSize: 5, 
       schema: { 
        model: { 
         id: "id", 
         fields: { 
          id: { editable: false, nullable: true }, 
          po_number: { type: "string" }, 
          note: { type: "string" }, 
          valid_start: { type: "date" }, 
          valid_end: { type: "date" }, 
          po_lines : { editable: false, nullable: true} 
         } 
        } 


       }, 
      }); 
    }); 

homeController.js

app.controller('homeController', function ($scope, $http, poDataSource, poLinesDataSource) { 

    $scope.onChange = function (e) { 

     $scope.showPoLines = true; 
     var grid = e.sender; 
     var selectedItem = grid.dataItem(grid.select()); 
     var selectedItemId = selectedItem.id; 

     $http({ 
      method: 'get', 
      url: 'api/polines/getlines', 
      params: { id: selectedItemId } 
     }) 
      .success(function (data) { 
       // new push new data to grid dataSource 
       $('#PoLinesGrid').data('kendoGrid').dataSource.data(data); 
       var grid2 = $('#PoLinesGrid').data('kendoGrid'); 
       grid2.dataSource.transport.options.create.url = "/api/polines/PostPO?=" + selectedItemId; 

      }) 
      .error(function (data) { 
       console.log(data); 
      }); 

    }; 
    $scope.dataSource = poDataSource; 

    $scope.gridColumns = [ 
      { field: "id", title: "ID" }, 
      { field: "po_number", title: "PO nr" }, 
      { field: "valid_start", title: "Start date" }, 
      { field: "valid_end", title: "End date" }, 
      { field: "note", title: "Note" }, 
      { 
       command: [{ template: "<button class='k-button' ng-click=''>PO lines</button>", }], 
       title: "PO lines" 
      }, 
      { template: "<input type='text' ng-value='calculateTotal(dataItem)' />", title: "Total" }, 
      { 
       command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>", }], 
       title: "Show details" 
      }, 

      { command: ["edit", "destroy"], title: " " } 
    ]; 


    $scope.dataSourceOfLines = poLinesDataSource; 

    $scope.gridColumnsOfLines = [ 
      { field: "id", title: "ID" }, 
      { field: "total", title: "Total" }, 
      { field: "note", title: "Note" }, 
      { command: ["edit", "destroy"], title: " " } 
    ]; 
}); 

Index.cshtml

<kendo-grid id="#PoGrid" k-data-source="dataSource" 
      k-columns="gridColumns" 
      k-editable="'inline'" 
      k-toolbar="['create']" 
      k-sortable="true" 
      k-pageable="true" 
      k-resizeable="true" 
      k-on-change="onChange(kendoEvent)" 
      k-selectable="true"> 
</kendo-grid> 
<div ng-show="showPoLines"> 
    <kendo-grid id="PoLinesGrid" k-data-source="dataSourceOfLines" 
       k-columns="gridColumnsOfLines" 
       k-editable="'inline'" 
       k-toolbar="['create']" 
       k-sortable="true" 
       k-pageable="true" 
       k-resizeable="true" 
       @*k-on-change="onChange(kendoEvent)"*@ 
       k-selectable="true"> 
    </kendo-grid> 
</div> 

Ich hoffe, dass Lösung dieses Problems auch anderen Menschen helfen kann. Auch ich danke Menschen, die mir helfen, diese Antwort zu finden.

2

batch wird true gesetzt, was bedeutet, dass die Kendo UI Datasource wird sende alle neuen Artikel in einer einzigen Anfrage im folio flügel weg:

models: [ 
    { FieldName1: "value 1.1", FieldName2: "value 2.1" }, 
    { FieldName1: "value 1.2", FieldName2: "value 2.2" } 
] 

Es scheint, dass der serverseitige Code derzeit dies nicht erwartet.

Entweder die Serverimplementierung ändern oder Stapeloperationen deaktivieren. Behalten Sie auch Ihre parameterMap Funktion im Auge, da sie auch direkten Einfluss darauf hat, wie Artikel gesendet werden.

http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-batch

http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.parameterMap

0

nach dem URI Decodierung Es sieht wie folgt aus,

"[{"id":null,"po_number":"1","note":"ojklj", 
"valid_start":"2016-08-09T10:06:46.‌​703Z","valid_end":"2016-08-09T10:06:46.703Z"}]" 

hier Sie ich PO Aktion erstellen eine Liste Server, aber in POST senden thare ist sehen können, also sollte es List<PO> sein oder Ihr Client-Code muss so geändert werden, dass er ein einzelnes Objekt senden soll.

, was ich würde empfehlen Ihnen, können Sie auch DatasourceRequest in Argumenten aufgerufen gesetzt etwas so können Sie erhalten alle Kendo unterstützt params.

mehr auf DatasourceRequest here und here