骨干模型有条件地触发事件,视图没有听到它

Backbone Model triggers event conditionally, View doesn't hear it

本文关键字:视图 事件 模型 有条件      更新时间:2023-09-26

我正在创建一个地理位置模型,从localStorage取回,并检查那里是否有一个纬度属性。如果没有,则触发'geolocation:city_state_blank'事件。如果听到'geolocation:city_state_blank',则触发@get_users_geolocation()

class App.GeoLocation extends Backbone.Model
    initialize: ->
       @on 'geolocation:city_state_blank', -> @get_users_geolocation()
       @fetch().always => 
         if @get('city_state').length is 0
           @trigger 'geolocation:city_state_blank'
         else
           @trigger('geolocation:done')


    get_users_geolocation: =>
        # Code to get / save (in localStorage) a users geolocation and city / state
        @trigger('geolocation:done')

get_users_geolocation()完成后触发geolocation:done事件。

我已经删除了获取用户geoLocation/反向geoLocation查找的细节,这些都是异步的。但所有这些工作的最终结果归结为触发geolocation:done事件。

class App.GeolocationView extends Backbone.View
   initialize: =>
      @listenTo @model, 'geolocation:done', =>
        alert('geolocation:done was heard in the view!!!!')

问题来了:

在场景中,当地理位置模型从localStorage获取并确定属性latitude未设置,因此调用get_users_geolocation -视图警报Geolocation:done在视图!!!!中被听到

但是在Geolocation具有纬度属性(else)并立即触发geolocation:done的场景中,View 不会发出任何警报。视图听不到

我控制台。记录了这一切,可以说流程是有效的。if/else正在工作并且视图正在正确地实例化。从localStorage获取后在回调中进行日志记录会产生以下结果:

@fetch().always => 
    console.log @get('current_city_state')
    console.log typeof @get('current_city_state')
    // Norfolk, VA
    // String

这里有数据…

发生什么事了??请帮助! !

我猜你的App.GeoLocationlatitude属性是一个数字。这将使您的测试看起来像这样:

if some_number.length is 0

数字没有length属性,所以@get('latitude').length将是未定义的,你剩下的是:

if undefined is 0

这将永远是假的,所以@trigger('geolocation:done')总是被调用。

如果您对latitude属性的存在感兴趣,那么CoffeeScript的存在运算符(?)将更好地为您服务:

if @get('latitude')?
    # There is a latitude.
else
    # No latitude.

要了解?的行为,你可以看看这是怎么做的:

class M extends Backbone.Model
m = new M(p: 0)
if m.get('p') == 0
    console.log('p == 0')
else
    console.log('p != 0')
if m.get('p')?
    console.log('there is a p')
else
    console.log('the p is a lie')
if m.get('no')?
    console.log('yes no')
else
    console.log('no no')    

显示p == 0there is a pno no

演示:http://jsfiddle.net/ambiguous/qmBNy/

我最终这样做了。它不漂亮,但它有效。

@listenTo @model, 'geolocation:done', =>        
   @prefill_location_input()
   @initialize_autocomplete()
@prefill_location_input()
@initialize_autocomplete()

我认为你是对的,事件是在init返回之前触发的。在这里,如果Object准备好了,@prefill_location_input()@initialize_autocomplete()被调用,geolocation:done将覆盖它,如果它是从网络获取的。