AngularJS在尝试轻松保存Changes时抛出异常

AngularJS throws exception when trying to saveChanges with breeze

本文关键字:保存 Changes 抛出异常 AngularJS      更新时间:2023-10-13

我是AngularJS和Breeze的新手。我正在尝试保存更改,但有问题。这是我的代码:

控制器内:

function update() {
        vm.loading = true;
        return datacontext.saveSettings().then(function () {
            vm.loading = false; // never gets called
        }).fail(function (data) {
            vm.loading = false; // never gets called
        });
    }

在数据上下文中:

 function saveSettings() {
        if (manager.hasChanges()) {
            manager.saveChanges() // breaks here if there are changes
                .then(saveSucceeded)
                .fail(saveFailed)
                .catch(saveFailed);
        } else {
            log("Nothing to save");
            return false;
        };
    }

错误是在angular.js中抛出的,这对TypeError: undefined is not a function没有帮助。我想我这里缺少了一些简单的东西,但我不知道是什么。

需要注意的是,它确实向服务器上的SaveChanges方法发送了正确的数据,但在收到来自服务器的任何响应之前就抛出了错误。收到响应后,它会抛出另一个错误TypeError: Cannot read property 'map' of undefined,但这可能与我返回的响应无效有关。我还没到那个部分。

有人能帮忙吗?我在这里迷路了。

更新

以下是我如何构建我的数据服务和管理器:

var serviceName = "http://admin.localhost:33333/api/breeze/"; // 
var ds = new breeze.DataService({
    serviceName: serviceName,
    hasServerMetadata: false,
    useJsonp: true,
    jsonResultsAdapter: jsonResultsAdapter
});
var manager = new breeze.EntityManager({ dataService: ds });
model.initialize(manager.metadataStore);

两个问题:

  1. 您的datacontext方法不返回promise,因此调用者找不到任何东西来挂起thenfail调用。

  2. 您应该呼叫catch,而不是fail

1.回报承诺

您的saveSettings方法在成功案例中没有返回结果,因此它一定失败了。在失败的情况下,您的方法还必须返回promise。。。否则它也会失败。

当我在这里的时候,由于成功和失败案例之间没有真正的区别,您不妨将vm.loading切换到finally子句。

试试这个:

function update() {
    vm.loading = true;
    return datacontext.saveSettings()
        .then(function () {
            // .. success handling if you have any
        })
        .catch(function (data) {
            // .. fail handling if you have any
        })
        .finally(funtion() {
            vm.loading = false; // turn it off regardless
        });
}

现在dataContext。。。注意,两个return语句返回了一个promise。

function saveSettings() {
    if (manager.hasChanges()) {
        return manager.saveChanges() 
            .then(saveSucceeded)
            .catch(saveFailed);
    } else {
        log("Nothing to save");
        // WHY ARE YOU FAILING WHEN THERE IS NOTHING TO SAVE? 
        // Breeze will handle this gracefully without your help
        return breeze.Q.reject(new Error('Nothing to save'));
    };
}

2.使用catch

我假设您已经将Breeze配置为使用Angular的$q进行promise(您应该使用"Breeze.Angular"服务,并在某个地方注入了"Breeze")。

$q没有fail方法!等效为catch。出于某种原因,您已将两者都附加到查询中。在服务器有机会响应之前,您将立即得到ReferenceError异常。。。尽管它会启动请求,您也会从服务器获得回调。

试试看:

return manager.saveChanges() 
    .then(saveSucceeded)
    .catch(saveFailed);

您可以看到许多Breeze示例调用failfin。这些是"Q.js"方法;"Q.js"是Breeze/KnockOut应用程序使用的另一个promise库,它是Angular的$q的基础。

"Q.js"和$q都支持现在标准的catchfinally promise方法。我们正在慢慢地将示例代码迁移到这个标准。在不同的场地里有很多旧的fail/finally代码。这需要时间。

很抱歉造成混乱。

如下更新savesetting函数以返回Promise

function saveSettings() {
    if (manager.hasChanges()) {
       return manager.saveChanges(); // return promise
    } else {
        log("Nothing to save");
        return false;
    };
}

然后您可以调用Then并在更新函数中失败,如下所示。

function update() {
    vm.loading = true;
    return datacontext.saveSettings().then(function () {
        vm.loading = false; // never gets called
    }).fail(function (data) {
        vm.loading = false; // never gets called
    });
}