2017-02-26 60 views
0

主函数如下,这将导致'setState'不是有效的属性异常。 api.js的如何将'this'对象传递给使用协议的函数中调用的回调函数apply

componentWillMount = function() { 
    api.daysOfMonth(this, this.props.month, this.props.year, function (ds) { 
     var days = []; 
     ds.forEach(function (jsonDay) { 
      var day = {date: jsonDay.date, inRange: jsonDay.inRange}; 
      days.push(day); 
     }); 

     this.setState({ daysOfMonth: days }); 
    }); 

片段是以下。 主函数调用Api.daysOfMonth(...),Api.daysOfMonth将使用全局对象来调用ajax方法并使用protocol apply调用回调函数,回调函数是从main函数传入的,如上脚本。

ApiImpl = (function() { 
 
       function ApiImpl() { } 
 
       
 
       ApiImpl.prototype.invoke = function (callerObj, callback, action) { 
 
        var params = []; 
 
        for (var _i = 3; _i < arguments.length; _i++) { 
 
         params[_i - 3] = arguments[_i]; 
 
        } 
 

 
        params.push(callback); //push callback function into params, so object of QWebChannel can callback the function after execute the 'action' 
 
        
 
        if (typeof window['api'] === 'undefined') { 
 
         new QWebChannel(qt.webChannelTransport, function (channel) { 
 
          window['api'] = channel.objects.api; 
 
          
 
          var func = window['api'][action].bind(callerObj); 
 
          return func.apply(callerObj, params); //here goes error 
 
         }); 
 
        } 
 
        
 
        var func = window['api'][action].bind(callerObj); 
 
        return func.apply(callerObj, params); //here goes error 
 
       }; 
 
       return ApiImpl; 
 
      }()); 
 
      Api = (function() { 
 
       function Api() { 
 
       } 
 
       Api.daysOfMonth = function (callerObj, month, year, callback) { 
 
        this.impl.invoke(callerObj, callback, 'daysOfMonth', month, year); 
 
       }; 
 
       return Api; 
 
      }()); 
 
      Api.impl = new ApiImpl(); 
 
      exports_1("Api", Api);

+0

你想'这个'是什么? 'jsonDay'? – zer00ne

回答

1

如果不回答你的问题,究其原因是因为.bind()结合新创建的功能this作为第一个参数传递了一个你。

componentWillMount = function() { 
    api.daysOfMonth(this, this.props.month, this.props.year, function (ds) { 
     var days = []; 
     ds.forEach(function (jsonDay) { 
      var day = {date: jsonDay.date, inRange: jsonDay.inRange}; 
      days.push(day); 
     }); 

     this.setState({ daysOfMonth: days }); 
    }.bind(this)); 

参见:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

请注意,如果你写ES6,您可以使用箭头功能做同样的事情。

componentWillMount = function() { 
    api.daysOfMonth(this, this.props.month, this.props.year, (ds) => { 
     var days = []; 
     ds.forEach(function (jsonDay) { 
      var day = {date: jsonDay.date, inRange: jsonDay.inRange}; 
      days.push(day); 
     }); 

     this.setState({ daysOfMonth: days }); 
    }); 

总之,this在箭头功能是词法作用域这意味着this保证是其中箭头函数定义相同this

另请参阅:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

+0

是的,你的解决方案OK!我把bind()放在内部函数中,我应该把它放在我的主函数中。非常感谢。 – SolardiaX

相关问题