在Backbone.js与Marionette中绑定Google Places Autocomplete的getPlace()结果
解决Ninja Forms自定义字段中Google Maps Places Autocomplete的上下文绑定问题
我来帮你搞定这个困扰!你遇到的核心问题其实是JavaScript回调函数里的this上下文跑偏了——默认情况下,place_changed的回调里this指向的是Google Autocomplete实例,而不是你的Backbone/Marionette视图实例,所以直接赋值this.formattedAddress根本没写到你想要的变量上。下面给你几个靠谱的解决方案:
方案1:用var self = this锁定上下文(兼容所有ES版本)
这个方法你已经尝试过,可能是代码里的位置不对?要确保在回调函数外部提前把视图实例存起来:
initialize: function() { // 先把当前视图实例存到self变量里 var self = this; // 初始化Google Places Autocomplete const inputElement = this.$el.find('.your-custom-input')[0]; const autocomplete = new google.maps.places.Autocomplete(inputElement); autocomplete.addListener('place_changed', function() { const selectedPlace = autocomplete.getPlace(); // 这里用self访问视图实例的formattedAddress self.formattedAddress = selectedPlace.formatted_address; console.log(self.formattedAddress); // 现在能正常输出 // 还可以触发Backbone事件通知其他组件,比如: self.trigger('address:updated', self.formattedAddress); }); // 提前初始化属性,避免回调外打印显示undefined this.formattedAddress = ''; }
方案2:用ES6箭头函数(简洁高效,现代环境推荐)
箭头函数会自动继承外部作用域的this,不用额外存变量,直接用this就是你的视图实例。Ninja Forms基于Backbone/Marionette,现代WordPress环境基本都支持ES6语法,放心用:
initialize: function() { const inputElement = this.$el.find('.your-custom-input')[0]; const autocomplete = new google.maps.places.Autocomplete(inputElement); autocomplete.addListener('place_changed', () => { const selectedPlace = autocomplete.getPlace(); // 直接用this访问视图实例属性 this.formattedAddress = selectedPlace.formatted_address; console.log(this.formattedAddress); }); this.formattedAddress = ''; }
方案3:用Underscore.js的_.bindAll(Backbone原生依赖,适合复杂逻辑)
如果你的回调逻辑比较复杂,可以把它抽成单独的方法,用Backbone自带的Underscore工具绑定上下文:
initialize: function() { // 把handlePlaceChanged方法的this绑定到当前视图实例 _.bindAll(this, 'handlePlaceChanged'); const inputElement = this.$el.find('.your-custom-input')[0]; const autocomplete = new google.maps.places.Autocomplete(inputElement); autocomplete.addListener('place_changed', this.handlePlaceChanged); this.formattedAddress = ''; }, handlePlaceChanged: function() { const inputElement = this.$el.find('.your-custom-input')[0]; const autocomplete = google.maps.places.Autocomplete.getInstance(inputElement); const selectedPlace = autocomplete.getPlace(); this.formattedAddress = selectedPlace.formatted_address; console.log(this.formattedAddress); }
额外注意点
- 一定要在视图初始化时提前给
formattedAddress赋值(比如空字符串),这样回调外打印的时候就不会显示undefined了。 - 如果是Marionette视图,别忘了确保你的字段渲染逻辑能响应
formattedAddress的变化,比如用model.set或者触发视图重绘事件。
内容的提问来源于stack exchange,提问作者Micheal J. Roberts
相关产品推荐
相关产品推荐

