0

複数の Google プレイス オートコンプリート フィールドを同じページに統合しようとしていますが、このダミー コードが機能する理由がわかりません。

$ ->
  options = types: ["(cities)"]

  insts = []
  elements = document.getElementsByClassName('autocomplete_city')

  insts[0] = new google.maps.places.Autocomplete(elements[0], options)
  google.maps.event.addListener insts[0], "place_changed", ->
    place = this.getPlace()
    datas = place.geometry.location.lat()+"::"+place.geometry.location.lng()

    $(elements[0]).next('input.autocomplete_city_id').val(datas)


  insts[1] = new google.maps.places.Autocomplete(elements[1], options)
  google.maps.event.addListener insts[1], "place_changed", ->
    place = this.getPlace()
    datas = place.geometry.location.lat()+"::"+place.geometry.location.lng()

    $(elements[1]).next('input.autocomplete_city_id').val(datas)

このループバージョンは機能しませんが:

$ ->
  options = types: ["(cities)"]

  insts = []
  elements = document.getElementsByClassName('autocomplete_city')

  i = 0
  for element in elements
    insts[i] = new google.maps.places.Autocomplete(element, options)

    google.maps.event.addListener insts[i], "place_changed", ->
      place = this.getPlace()
      datas = place.geometry.location.lat()+"::"+place.geometry.location.lng()

      $(element).next('input.autocomplete_city_id').val(datas)

    i += 1

この場合、最初のオートコンプリート入力を入力しても、最後の 'autocomplete_city_id' のみがオートコンプリート データで埋められます (= レシーバーの「要素」変数は常に配列の最後の変数です)。

これらの 2 つのスニペットはまったく同じではありませんか、それとも深刻な Javascript OOP 原則が欠けていますか? それはCoffeescriptトラップですか?

4

2 に答える 2

2

CoffeeScriptのウェブサイトで述べたように:

JavaScript ループを使用して関数を生成する場合、ループ変数が確実に閉じられるようにするためにクロージャー ラッパーを挿入するのが一般的であり、生成されたすべての関数が最終的な値を共有するだけではありません。CoffeeScript は do キーワードを提供します。これは、渡された関数をすぐに呼び出し、引数を転送します。

おそらく次のようにコードを変更できます。

$ ->
  options = types: ["(cities)"]

  insts = []
  elements = document.getElementsByClassName('autocomplete_city')

  i = 0
  for element in elements
    do (element) ->
      insts[i] = new google.maps.places.Autocomplete(element, options)

      google.maps.event.addListener insts[i], "place_changed", ->
        place = this.getPlace()
        datas = place.geometry.location.lat()+"::"+place.geometry.location.lng()

        $(element).next('input.autocomplete_city_id').val(datas)

      i += 1

その他:forステートメントは のように使用できますfor element, indexi = 0その後、とその増分を削除できます。

于 2013-10-01T12:56:42.157 に答える
0

push私の提案は、コンパイルされたjsのメソッドによって奇妙な動作が発生する可能性があるということです。

コードを少しリファクタリングreturnし、ループに追加しました。

$ ->
  options = types: ["(cities)"]

  insts = []
  elements = document.getElementsByClassName('autocomplete_city')

  for element, i in elements
    insts[i] = new google.maps.places.Autocomplete(element, options)

    google.maps.event.addListener insts[i], "place_changed", ->
      place = @.getPlace()
      datas = "#{place.geometry.location.lat()}::#{place.geometry.location.lng()}"
      $(element).next('input.autocomplete_city_id').val(datas)
      return
    return
于 2013-10-01T12:47:42.733 に答える