【问题标题】:jaydata 1.5 with odata 4 and angularjs - errors when saving / updating data带有 odata 4 和 angularjs 的 jaydata 1.5 - 保存/更新数据时出错
【发布时间】:2016-05-08 22:50:52
【问题描述】:

我将 jaydata 1.5.1 与 odata 4 和 ASP.Net WebAPI OData 4 一起使用。不幸的是,jaydata 网站上的几乎所有示例都是针对旧版本的 jaydata 本身或 1.5 + odata 4 + angularjs 的合适示例,这至少让我觉得这个项目(jaydata)快要死了。

我设法启动了 jaydata 服务并请求数据。但是,一旦我尝试操作数据(添加、编辑、保存),我就会遇到由于缺乏文档而无法解决的错误。请在这里找到我到目前为止的代码:

index.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Cache-Control" content="no-store" />
<meta charset="utf-8" />

<link href="Content/bootstrap.min.css" rel="stylesheet" />
<link href="css/font-awesome.min.css" rel="stylesheet" />
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/odatajs-4.0.0/odatajs-4.0.0.min.js"></script>

<script src="Scripts/angular.min.js"></script>

<script src="Scripts/jaydata/jaydata.js"></script>
<script src="Scripts/jaydata/jaydatamodules/angular.min.js"></script>
<!--<script src="Scripts/jaydata/jaydataproviders/oDataProvider.min.js"></script>-->
<!--<script src="app/model.js"></script>-->

<script src="app/app.js"></script>

</head>
<body data-ng-app="app">

<div ng-controller="ItemController">
    <ul>
        <li ng-repeat="item in Items">
            <input id="checkSlave" type="checkbox" ng-model="item .IstAktiv">
            {{item .Vorname}} {{item .Name}} ({{item .Klinik}} - {{item .Abteilung}} : {{item .Station}})
        </li>
    </ul>
        <button ng-click="newItem()">add new</button>
    <p>
        <form ng-if="selectedItem">
            <fieldset style="width: 300px; background-color: #0094ff;">
                <legend>{{selectedItem.Name}}</legend>
                <br />
                <label>
                    <table class="table table-striped table-bordered table-condensed">
                        <thead>
                            <tr>
                                <td class="text-center">Aktiv</td>
                                <td class="text-center">Vorname</td>
                                <td class="text-center">Name</td>
                                <td class="text-center">Klinik</td>
                                <td class="text-center">Abteilung</td>
                                <td class="text-center">Station</td>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td class="text-center"><input id="checkSlave" type="checkbox" ng-model="selectedItem.IstAktiv"></td>
                                <td class="text-center"><input ng-model="selectedItem.Vorname" size="20" /></td>
                                <td class="text-center"><input ng-model="selectedItem.Name" size="20" /></td>
                                <td class="text-center"><input ng-model="selectedItem.Klinik" size="20" /></td>
                                <td class="text-center"><input ng-model="selectedItem.Abteilung" size="20" /></td>
                                <td class="text-center"><input ng-model="selectedItem.Station" size="20" /></td>

                            </tr>
                        </tbody>
                    </table>
                </label>
                    <button ng-click="save()">Save</button>
                    <button ng-click="remove()">Remove</button>
</fieldset>
        </form>
    </p>
</div>
</body>
</html>

app.js:

var app = angular.module('app', ['jaydata']);

app.controller('ItemController', ['$scope', '$data', function ($scope, $data, $q) {
    $scope.Items = [];
    $scope.selectedItem = null;

    $data.initService('http://odata/test/JaydataTest/')
        .then(function (context) {
            $scope.context = context;
            context
                .Items
                //.map(function (p) { return p.Name })
                //.select("{ CategoryObject: it.Category, Name: it.Name }")
                //.filter(function (item) {  item.Name.startsWith('Kim');})
                // .filter(function (product) { return product.Id > idParam }, { idParam: 2 })
                //.find(2)
                //.orderBy(function (item) {item.Klinik})
                .toArray()
                .then(function (result) {
                    $scope.Items = result;
                    $scope.$apply();
                })
        })
        .catch(function (error) {
            alert(error);
        });

    $scope.save = function () {
        if ($scope.selectedItem.ItemId) {
            // save existing
            $scope.context.Items.attach($scope.selectedItem, true);
            $scope.selectedItem.entityState = $data.EntityState.Modified;
        }
        else {
            // save new
            $scope.context.Items.add($scope.selectedItem, true);
        }
        $scope.saveChanges();
    };

    $scope.saveChanges = function () {

        $scope.context.saveChanges()
            .then(function (n) {
                $scope.selectedItem = null;
                $scope.$apply();
            })
            .fail(function (error) { console.log(error); });
    }

    $scope.newItem = function () {
        var ctx = $scope.context;
        $scope.selectedItem = new ctx.Items.elementType({Name: "new Item"})
    };
}])

我收到以下错误:

1) 保存时,数据已正确保存到底层数据库,但出现以下控制台错误,上下文未更新,新项目仅在刷新页面后才显示 (angular.js = jaydatamodules /angular.js):

TypeError: n.call(...).then(...).fail is not a function
    at Container.a.default.EntityContext.saveChanges (angular.js:266)
    at n.$scope.saveChanges (app.js:112)
    at n.$scope.save (app.js:91)
    at fn (eval at <anonymous> (angular.js:14432), <anonymous>:4:203)
    at b (angular.js:15485)
    at e (angular.js:25018)
    at n.$eval (angular.js:17229)
    at n.$apply (angular.js:17329)
    at HTMLButtonElement.<anonymous> (angular.js:25023)
    at HTMLButtonElement.x.event.dispatch (jquery-1.10.2.min.js:22)

我尝试了不同的语法(then/fail then/catch success/error callback),但无法绕过这个错误。有什么想法吗?

2) 虽然保存数据有效,但更新无效。我收到以下错误:

PATCH http://odata/test/JaydataTest//Items(21) 400 (Bad Request) @  odatajs-4.0.0.js:4366

Exception {name: "HTTP request failed", message: "The request is invalid.", data: Object} @ jaydata.js:4315

oDataProvider.js:4156 Uncaught (in promise) Exception {name: "HTTP request failed", message: "The request is invalid.", data: Object}

如何解决这个错误?

ODataController:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.ModelBinding;
using System.Web.OData;
using System.Web.OData.Query;
using System.Web.OData.Routing;
using Model;

namespace JaydataTest.Controllers.odata
{
    /*
    The WebApiConfig class may require additional changes to add a route for this controller. Merge these statements into the Register method of the WebApiConfig class as applicable. Note that OData URLs are case sensitive.

    using System.Web.OData.Builder;
    using System.Web.OData.Extensions;
    using Model;
    ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<Item>("Items");
    config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
    */
    public class ItemsController : ODataController
    {
        private ModelContext db = new ModelContext();

        // GET: odata/Items
        [EnableQuery]
        public IQueryable<Item> GetItems()
        {
            return db.Items;
        }

        // GET: odata/Items(5)
        [EnableQuery]
        public SingleResult<Item> GetItem([FromODataUri] int key)
        {
            return SingleResult.Create(db.Items.Where(item => item.ItemId == key));
        }

        // PUT: odata/Items(5)
        public IHttpActionResult Put([FromODataUri] int key, Delta<Item> patch)
        {
            Validate(patch.GetEntity());

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            Item item = db.Items.Find(key);
            if (item == null)
            {
                return NotFound();
            }

            patch.Put(item);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ItemExists(key))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return Updated(item);
        }

        // POST: odata/Items
        public IHttpActionResult Post(Item item)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.Items.Add(item);
            db.SaveChanges();

            return Created(item);
        }

        // PATCH: odata/Items(5)
        [AcceptVerbs("PATCH", "MERGE")]
        public IHttpActionResult Patch([FromODataUri] int key, Delta<Item> patch)
        {
            Validate(patch.GetEntity());

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            Item item = db.Items.Find(key);
            if (item == null)
            {
                return NotFound();
            }

            patch.Patch(item);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ItemExists(key))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return Updated(item);
        }

        // DELETE: odata/Items(5)
        public IHttpActionResult Delete([FromODataUri] int key)
        {
            Item item = db.Items.Find(key);
            if (item == null)
            {
                return NotFound();
            }

            db.Items.Remove(item);
            db.SaveChanges();

            return StatusCode(HttpStatusCode.NoContent);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool ItemExists(int key)
        {
            return db.Items.Count(e => e.ItemId == key) > 0;
        }
    }
}

jaydatamodules/angular.js(摘录)

var originalSave = $data.Entity.prototype.save;
var originalRemove = $data.Entity.prototype.remove;
var originalSaveChanges = $data.EntityContext.prototype.saveChanges;

        $data.EntityContext.prototype.saveChanges = function () {
            var _this = this;
            var d = $q.defer();
            originalSaveChanges.call(_this).then(function (n) {
                cache = {};
                d.resolve(n);
                if (!$rootScope.$$phase) $rootScope.$apply();
            }).fail(function (err) {
                d.reject(err);
                if (!$rootScope.$$phase) $rootScope.$apply();
            });
            return d.promise;
        }
        return $data;
    }]);

非常感谢您的帮助。提前致谢

【问题讨论】:

    标签: javascript angularjs odata asp.net-web-api2 jaydata


    【解决方案1】:

    我建议您查看 JayData angular2 quickstartjaydata odata v4 example 存储库。 两者都使用不再需要 odatajs 的 JayData 1.5.5 RC,因为它已经包含了它的补丁版本。

    【讨论】:

    • 回到这个话题检查更新,我想到的是:JayData v1.5.5已经包含必要的odatajs lib,所以错误可能是由加载的那个引起的。尝试删除加载 odatajs 的
    【解决方案2】:

    您必须包含以下模块:

    <script src="Scripts/jaydatamodules/deferred.js"></script>
    

    http://jaydata.org/blog/how-to-work-with-the-jaydata-promise-interfaces

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      相关资源
      最近更新 更多