在Angular Service/Controller中实现安全$apply的最佳方法
Best approach to implement safe $apply in Angular Service/Controller
我在Angular WebApp中使用socket.io
客户端。我把它包装在一个服务中,但这可能不一定感兴趣。然而,由于传入的数据与使用该服务的控制器处于不同的范围,因此我总是必须调用$scope.$apply
。更糟糕的是,我发现了一些情况(在连接/重新连接期间),我必须使用这里解释的safeApply
。
我知道这是一个角度反模式,但我看不到解决这个问题的方法。
有没有一种通用的方法来解决这个问题(最好是在服务内部),不会用大量的$scope.$apply/safeApply
污染控制器?
BR,Daniel
这里也有一些代码,工作,但不好:
angular.module('mean')
.controller('ConnectionStateController', function ($scope) {
$scope.safeApply = function (fn) {
var phase = this.$root.$$phase;
if (phase == '$apply' || phase == '$digest') {
if (fn && (typeof (fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
var socket = io.connect('http://localhost:3000');
$scope.message = 'Not connected';
socket.on('connect', function () {
$scope.safeApply(function () {
$scope.message = "Connected";
});
});
});
在您的案例中,您知道socket.io
操作总是异步运行,这使得它成为使用$scope.$apply
的有效位置(位于页面底部)。
我建议不要使用safeApply
,而是显式调用$scope.$apply
。使用safeApply
将掩盖实现中的真正错误。此外,如果您将代码封装在服务中,则可以在服务中注入$rootScope
并调用$rootScope.$apply
中的异步函数。那么您就不需要在每个控制器中调用$scope.$apply
。
我会自己回答这个问题,因为我有一个使用defer
s的有效解决方案。然而,我不确定我做得是否正确。这是服务:
angular.module('mean')
.factory('ConnectionService', function ($q, $timeout) {
var bindings = {};
var socket = io.connect('http://localhost:3000');
// catch all events by overriding the socket's $emit
var $emit = socket.$emit;
socket.$emit = function (event, obj) {
console.log('***', 'on', '"' + event + '"', obj);
if (bindings.hasOwnProperty(event)) {
bindings[event].notify(obj);
}
$emit.apply(socket, arguments);
};
return {
socket: socket,
observe: function (event, callback) {
if (!bindings.hasOwnProperty(event)) {
bindings[event] = $q.defer();
}
bindings[event].promise.then(null, null, function (data) {
callback.apply(this, [ data ]);
});
}
};
});
这允许控制器使用这样的服务:
ConnectionService.observe('news', function (data) {
$scope.message = data;
});
不确定,这是一个好的解决方案,还是有副作用,我还没有看到。
BR,Daniel
相关文章:
- Javascript:如何获取函数.apply()的键
- 在localhost Dev Box上测试JSONP请求的最佳方式
- 有条件更新d3.js力图中节点的最佳方法
- 为react组件传递道具的最佳方式
- 与运行长作业(javascript,node.js)的第三方API同步的最佳实践
- 让Webpack管理Quirky AMD定义的最佳方式
- 在承诺链中处理早期回报的最佳方式
- 将jQuery.ech()方法转换为本地JavaScript抽象的最佳方法是什么
- Angularjs 1.5.x本地化最佳实践
- 处理浮点错误的最佳方法是什么
- 另一个if(!$scope.$$phase)$scope$apply()szenario-需要帮助才能通关
- javascript导入的最佳实践是什么
- MobileFirst:在客户端运行计时器作业-最佳选项
- 在ng重复循环中显示条件内容的最佳方式是什么
- 在phonegap中为android调用onload函数的最佳方式
- call()和apply()实际上是用来欺骗方法处理类似数组的对象的
- 实现比较方法的最佳实践是什么;s的比较类型是在运行时选择的
- 从数组中删除元素的最佳方法是:javascript/jquery
- 使用$scope的最佳实践$apply();或者甚至是使用Angular Component的非Angular内容中的$
- 在Angular Service/Controller中实现安全$apply的最佳方法