我想从我的请求“instance.web.Model”获得结果,然后调用this.super()。问题是“instance.web.Model”是异步的,所以在我的情况下,super()将在请求完成之前被调用。
MyObject.extend({
init: function(parent, data){
var newData = instance.web.Model('advanced.search')
.call('check_duplication', [data]).done(function (name) {
// do stuff
return name
});
data = newData;
this._super.apply(this, arguments);
// super is called before my request is done so the new data are not sent to super.
}
});
你知道如何度过难关吗?为了将newData而不是数据作为参数传递给超级对象。
PS:我试图将其封装在自我中:var self = this;但它不起作用,因为我似乎扩展的父对象继续运行而不等待。所以我得到了像“self.super(......不是函数)”这样的错误。
MyObject.extend({
init: function(parent, data){
var self = this;
var newData = instance.web.Model('advanced.search')
.call('check_duplication', [data]).done(function (name) {
// do stuff
var newData = name;
self._super.apply(self, parent, newData);
// or self._super.apply(self, arguments); etc... I tried many variantes
});
}
});
回答Bergi,因为他问我_super()正在调用什么。 instance.web.Model在服务器端调用python脚本,我想这是一种Ajax调用。但我测试了很多情况,我假设这个instance.web.Model调用是异步的。这就是我扩展的对象:
instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @lends instance.web.search.ExtendedSearchProposition# */{
template: 'SearchView.extended_search.proposition',
events: {
'change .searchview_extended_prop_field': 'changed',
'change .searchview_extended_prop_op': 'operator_changed',
'click .searchview_extended_delete_prop': function (e) {
e.stopPropagation();
this.getParent().remove_proposition(this);
}
},
/**
* @constructs instance.web.search.ExtendedSearchProposition
* @extends instance.web.Widget
*
* @param parent
* @param fields
*/
init: function (parent, fields) {
this._super(parent);
this.fields = _(fields).chain()
.map(function(val, key) { return _.extend({}, val, {'name': key}); })
.filter(function (field) { return !field.deprecated && (field.store === void 0 || field.store || field.fnct_search); })
.sortBy(function(field) {return field.string;})
.value();
this.attrs = {_: _, fields: this.fields, selected: null};
this.value = null;
},
更进一步(希望它能帮到你)。好的,让我们看看谁是超类:
instance.web.Widget = instance.web.Controller.extend({
// Backbone-ish API
tagName: 'div',
id: null,
className: null,
attributes: {},
events: {},
/**
* The name of the QWeb template that will be used for rendering. Must be
* redefined in subclasses or the default render() method can not be used.
*
* @type string
*/
template: null,
/**
* Constructs the widget and sets its parent if a parent is given.
*
* @constructs instance.web.Widget
*
* @param {instance.web.Widget} parent Binds the current instance to the given Widget instance.
* When that widget is destroyed by calling destroy(), the current instance will be
* destroyed too. Can be null.
*/
init: function(parent) {
this._super(parent);
// Bind on_/do_* methods to this
// We might remove this automatic binding in the future
for (var name in this) {
if(typeof(this[name]) == "function") {
if((/^on_|^do_/).test(name)) {
this[name] = this[name].bind(this);
}
}
}
// FIXME: this should not be
this.setElement(this._make_descriptive());
this.session = instance.session;
},
然后,下一个:
instance.web.Controller = instance.web.Class.extend(instance.web.PropertiesMixin, {
/**
* Constructs the object and sets its parent if a parent is given.
*
* @param {instance.web.Controller} parent Binds the current instance to the given Controller instance.
* When that controller is destroyed by calling destroy(), the current instance will be
* destroyed too. Can be null.
*/
init: function(parent) {
instance.web.PropertiesMixin.init.call(this);
this.setParent(parent);
},
然后:
instance.web.PropertiesMixin = _.extend({}, instance.web.EventDispatcherMixin, {
init: function() {
instance.web.EventDispatcherMixin.init.call(this);
this.__getterSetterInternalMap = {};
},
然后:
instance.web.EventDispatcherMixin = _.extend({}, instance.web.ParentedMixin, {
__eventDispatcherMixin: true,
init: function() {
instance.web.ParentedMixin.init.call(this);
this.__edispatcherEvents = new Events();
this.__edispatcherRegisteredEvents = [];
},
最后:
instance.web.ParentedMixin = {
__parentedMixin : true,
init: function() {
this.__parentedDestroyed = false;
this.__parentedChildren = [];
this.__parentedParent = null;
},
答案 0 :(得分:1)
我不认为大多数框架提供的动态super
方法确实异步工作 - 但是如果你使用promises,它确实需要(promises总是异步的)。
因此,如果您需要从promise回调中调用父级的初始化方法,您可以尝试
MyObject.extend({
init: function(parent, data){
var _super = this._super.bind(this);
instance.web.Model('advanced.search')
.call('check_duplication', [data])
.done(function (name) {
_super(parent, name);
});
// or in short, even just:
// .done(this._super.bind(this, parent));
}
});
或者根本不使用_super
native capability来引用您的父类:
MyObject.extend({
init: function(parent, data){
var self = this;
instance.web.Model('advanced.search')
.call('check_duplication', [data])
.done(function (name) {
instance.web.search.ExtendedSearchProposition.prototype.init // or whatever the parent method is
.call(self, parent, newData);
});
}
});