0

我是 Breeze 的新手,我正在创建一个示例来学习。我面临一个问题。我创建了一个datacontext.js,在其中添加了轻量级代码以从服务中获取数据,如下所示

sample.factory('datacontext', ['breeze', 'Q', '$timeout', '$q', function (breeze, q, timeout, $q) {
configureBreeze();
var manager = new breeze.EntityManager("/breeze/ProductsBreeze");
manager.enableSaveQueuing(true);

var datacontext = {
    metadataStore: manager.metadataStore,
    getTodoLists: getTodoLists
};
function getTodoLists(onsuccess) {
    var query = breeze.EntityQuery.from("GetAllProducts");
    manager.executeQuery(query).then(onsuccess);

};
return datacontext;
//function getSucceeded(data) {
//    return data.results;
//}
function configureBreeze() {
    breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);

    // configure to use camelCase
    breeze.NamingConvention.camelCase.setAsDefault();
}
}]);

现在在getTodoLists我正在传递一个回调onsuccess。这是我的控制器

sample.controller('todoBreeze', ['datacontext', '$scope', '$log', function (datacontext, $scope, log) {
$scope.heading = "Hello World";
$scope.Products = [];
datacontext.getTodoLists(function (data) {
    $scope.Products = data.results;
    log.info($scope.Products);

});
$scope.editProduct = function (pid, index) {
};
$scope.deleteProduct = function (pid, index) {

};
}]);

现在的问题是它表明在完成请求后我的数组中有两条记录(显示在控制台中)但是如果我使用 UI 则不会更新

<span>{{Products.length}}</span>

但如果我$scope.$apply()在请求完成后打电话,那么它的工作正常。

你能告诉我我的代码中有什么错误吗?

谢谢

4

1 回答 1

0

请参阅下面的更新。

$scope.$apply() 函数用于将代码放回“AngularJS 世界”。

当像您一样使用第三方库时,这正是您在 AngularJS 摘要循环中执行代码所需要的。当您使用具有回调的 AngularJS 服务时,它们已经在后台调用 $apply() 并将代码放回 AngularJS 的摘要循环中。

在您的情况下,您创建了自己的服务并在控制器中将回调传递给它。当调用该回调时,您已经在 AngularJS 摘要循环之外,因此 AngularJS 不会注意到范围发生了变化。调用 $apply 函数将代码设置回 AngularJS 的摘要循环,让 AngularJS 看到范围发生了变化。

可以在http://jimhoskins.com/2012/12/17/angularjs-and-apply.html找到更详细的 $scope.$apply 指南

因此,您可以像这样更改工厂代码以包含 $apply 调用:

sample.factory('datacontext', ['breeze', 'Q', '$timeout', '$q', '$rootScope', function (breeze, q, timeout, $q, $scope) {
configureBreeze();
var manager = new breeze.EntityManager("/breeze/ProductsBreeze");
manager.enableSaveQueuing(true);

var datacontext = {
    metadataStore: manager.metadataStore,
    getTodoLists: getTodoLists
};
function getTodoLists(onsuccess) {
    var query = breeze.EntityQuery.from("GetAllProducts");
    manager.executeQuery(query).then($rootScope.$apply(onsuccess));
};
return datacontext;

这样你就不需要在每个使用你的服务的控制器上调用它。

更新:

我被你关于 $scope.$apply() 的句子误导了。这就是为什么最好提供一个工作示例,以便我们可以使用它。

我认为问题在于您正在更改设置 $scope.Products 变量的引用。当你初始化它时

$scope.Products = []

您创建一个数组 A 并使 Products 引用该数组。然后在回调中更改 Products 引用的数组

$scope.Products = data.results;

尝试通过 data.results 数组并将其推送到 Products 数组,看看是否有帮助。

于 2013-10-12T16:54:07.597 回答