请考虑以下控制器的angularjs代码:
(function (app) {
var controller = function ($scope, $state, datacontext) {
$scope.$parent.manageTitle = "Account Management";
$scope.accounts = [];
var init = function () {
getRecords();
};
var getRecords = function () {
return datacontext.getAccounts().then(function (data) {
$scope.$apply(function () {
$scope.accounts = data;
});
});
};
init();
};
app.controller("accountsCtrl", ["$scope", "$state", "datacontext", controller]);
})(angular.module("app"));删除数据包装器并在getRecords方法中只保留"$scope.accounts = $scope.$apply“会破坏代码。检索数据,但是html中的ng-repeat指令不会自动更新。我正在尝试使用整个$apply/$digest模型,但在这种情况下,似乎不应该需要$apply。
我做错了什么吗?
谢谢。
<->
好的,谢谢你的回复。下面是数据上下文。它使用Breeze。我仍然不明白问题出在哪里--我就是不明白为什么上面的代码需要$apply。
(function (app) {
var datacontext = function () {
'use strict';
breeze.config.initializeAdapterInstance('modelLibrary', 'backingStore', true);
breeze.config.initializeAdapterInstance("ajax", "angular", true);
breeze.NamingConvention.camelCase.setAsDefault();
var service;
var manager = new breeze.EntityManager('api/ProximityApi');
var entityQuery = breeze.EntityQuery;
var queryFailed = function (error) {
};
var querySuccess = function (data) {
return data.results;
};
var getAccounts = function () {
var orderBy = 'accountName';
return entityQuery.from('Accounts')
.select('id, accountName')
.orderBy(orderBy)
.using(manager)
.execute()
.then(querySuccess, queryFailed);
};
service = {
getAccounts: getAccounts
};
return service;
};
app.factory('datacontext', [datacontext]);
})(angular.module('app'));再次感谢!
发布于 2014-05-10 22:11:21
谢谢你的回答。贾里德-你说的没错。默认情况下,Breeze不使用angular $q承诺,而是使用第三方Q.js承诺。因此,我需要$apply将VM同步到视图。然而,最近Breeze团队创建了angular.breeze.js,它允许Breeze代码使用angular promises。通过在应用程序中包含angular.breeze模块,所有Breeze代码都将使用原生angular promises和$http。
这解决了我的问题,我可以删除$apply调用。
请参阅:http://www.breezejs.com/documentation/breeze-angular-service
发布于 2014-05-10 07:15:35
需要使用$apply函数的原因是使用Breeze to返回数据的结果。$apply函数用于获取angular,以便对所有内部监视运行摘要并相应地更新作用域。当所有更改都发生在角度范围内时,这是不需要的,因为它会自动执行此摘要。在你的代码中,因为你使用的是Breeze,所以更改发生在angular作用域之外,因此你需要让angular手动运行摘要,这对于发生在angular之外的任何事情都是正确的(jQuery,其他框架等等)。确实,Breeze正在使用promises更新数据,但是Angular不知道如何处理promise返回后的更改,因为它超出了作用域。如果你使用的是angular服务和promises,那么视图将会自动更新。如果您的代码工作正常,那么以这种方式使用$apply将是正确的方式。
我唯一建议的是更改调用apply的方式,以确保它仅在当前没有另一个摘要正在进行时才会运行,因为这可能会导致摘要错误。我建议你这样调用这个函数:
if(!$scope.$$phase){$scope.$apply(function () {
$scope.accounts = data;
});或者,另一种选择是像这样的SafeApply编写一个围绕$apply函数的自定义包装器
https://stackoverflow.com/questions/23569128
复制相似问题