我正在使用库ParallelJS在Web worker中进行加密/解密,但是当promise被解析时,它不会根据模型的更改来更新视图。现在,我知道我必须在$ scope中包含在angularjs范围之外调用的代码。$ apply,但即使这样做也无济于事。
我认为原因是我正在解析一个在angular的范围外调用的回调中的延迟对象。这有点难以解释所以让我展示我的代码:
function _encrypt(options){
... //crypto-js code to do AES encryption
}
function _decrypt(options){
... //crypto-js code to do AES decryption
}
angular.module('CryptoService', []).factory('Cryptor', function($q, $rootScope){
function Cryptor(){};
Cryptor.prototype = {
encrypt: function(string, key) {
var deferred = $q.defer();
var ivS = generateIV();
var p = new Parallel({
iv: ivS,
text: string,
key: key
}, { evalPath: '/assets/js/eval.min.js' });
p.require('/assets/js/crypto.min.js');
p.spawn(_encrypt).then(function(result){
deferred.resolve(result);
});
return deferred.promise;
},
decrypt: function(string, key) {
var deferred = $q.defer();
var p = new Parallel({
text: string,
key: key
}, { evalPath: '/assets/js/eval.min.js' });
p.require('/assets/js/crypto.min.js');
p.spawn(_decrypt).then(function(result){
deferred.resolve(result);
});
return deferred.promise;
}
};
return new Cryptor();
});
angular.module('ContactService', ['CryptoService']).factory('Contact', function($q, $rootScope, Cryptor){
function Contact(){
//initialization
};
Contact.prototype = {
query: function(){
var deferred = $q.defer();
var options = {};
_oauth.secureGET(this._endpoint,options).done(function(result){
Cryptor.decrypt(result.cmc, key).then(function(string){
var data = JSON.parse(string);
var contacts = [];
for (var cidx in data){
var objContact = data[cidx];
var c = new Contact();
for(var pidx in this._properties){
var property = this._properties[pidx];
c[property] = objContact[property];
}
contacts.push(c);
}
//Since _oauth is using a jQuery method to execute the requests we are outside of angularjs' scope, so we need to wrap the promise resolution in
//the $apply method of the rootscope
$rootScope.$apply(function(){
deferred.resolve(contacts);
});
});
}.bind(this)).fail(function() {
$rootScope.$apply(function(){
deferred.resolve([]);
});
});
return deferred.promise;
},
};
return new Contact();
});
现在发生了什么:如果我离开代码,则永远不会调用查询方法的回调函数,因为在cryptor服务中,promise在angular的范围之外被调用。如果我将$ rootScope。$ apply wrapper移动到Cryptor服务,则调用Contact服务中的回调,调用控制器内部的回调,但视图不会更新。
有关如何解决此问题的任何提示?
谢谢大家
一个。
答案 0 :(得分:1)
好的,我觉得很蠢......问题不在于视图没有更新,而是模型为空。由于我错过了bind(this)
到Cryptor promise的回调,模型是空的,视图没有显示任何内容。改变这个
Cryptor.decrypt(result.cmc, key).then(function(string){
var data = JSON.parse(string);
var contacts = [];
for (var cidx in data){
var objContact = data[cidx];
var c = new Contact();
for(var pidx in this._properties){
var property = this._properties[pidx];
c[property] = objContact[property];
}
contacts.push(c);
}
//Since _oauth is using a jQuery method to execute the requests we are outside of angularjs' scope, so we need to wrap the promise resolution in
//the $apply method of the rootscope
$rootScope.$apply(function(){
deferred.resolve(contacts);
});
});
到此:
Cryptor.decrypt(result.cmc, key).then(function(string){
...
}.bind(this));
做了这个伎俩。
答案 1 :(得分:0)
从你的代码:
p.spawn(_encrypt).then(function(result){
deferred.resolve(result);
});
Parallel.js的Promise与Angular.js中的承诺不同。所以你需要换行
deferred.resolve(result);
进入Angular.js $ timeout:
$timeout(function(){
deferred.resolve(result);
}, 0)
以便通知Angular.js