AngularJS 在尝试使用 breeze 保存更改时抛出异常

AngularJS throws exception when trying to saveChanges with breeze

我是 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,但这可能与响应 I return 无效有关。我还没到那部分。

任何人都可以帮忙吗?我迷路了。

更新

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

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);

savesetting 函数更新为 return 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
    });
}

两个问题:

  1. 您的 datacontext 方法没有 return 承诺,因此调用者找不到任何东西来挂起 thenfail 调用。

  2. 你应该打电话给catch,而不是fail

1。 Return一个承诺

您的 saveSettings 方法没有 return 成功案例的结果,因此它一定会失败。您的方法还必须 return 失败情况下的承诺...否则它也会失败。

虽然我在这里,但由于您的成功和失败案例之间没有真正的区别,您不妨将 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 语句 return 一个承诺。

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 作为承诺(您应该使用 "breeze.angular" 服务并在某处注入 "breeze")。

$q does not have a fail method!等价于 catch。出于某种原因,您都已附加到您的查询中。在服务器有机会响应之前,您会立即收到 ReferenceError 异常...尽管它会启动请求并且您也会从服务器收到回调。

尝试一下:

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

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

的基础

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

抱歉造成混淆。