2016-01-23 149 views
1

我寫了這段代碼,希望運行後document.ready()部分的widget_controller屬性對search_form.widget_date_range對象將成爲控制器。令我驚訝的是,它是undefined。這裏出了什麼問題?爲什麼不按我希望的那樣工作?

search_form.widget_date_range = (function() { 
    var element_selector = "div.date-range-slider"; 
    var settings = { 
    bounds: { 
     min: new Date(2003, 0, 1), 
     max: new Date() 
    }, 
    defaultValues: { 
     min: new Date(2003, 0, 1), 
     max: new Date() 
    }, 
    wheelMode: "zoom", 
    }; 
    var widget_controller = {}; 
    var onDocumentReady = function() { 
    widget_controller = $(element_selector).dateRangeSlider(settings); 
    widget_controller.on("valuesChanged", onDataChange); 
    console.log(widget_controller); 
    }; 
    var onDataChange = function(e, data) { 
    // alert("Value just changed. min: " + data.values.min + " max: " + data.values.max); 
    $("form#searching").trigger("submit"); 
    }; 
    return { 
    onDocumentReady: onDocumentReady, 
    widget_controller: widget_controller 
    }; 
})(); 

$(document).ready(function() { 
    ... 
    search_form.widget_date_range.onDocumentReady(); 
}); 
+0

您的onDocumentReady()函數沒有被調用?那是怎麼回事? –

+0

在嘗試將widget_date_range屬性寫入它之前,search_form是否有值? 這可能是變量提升的標誌。你準備好的函數中的任何地方是否聲明「var search_form」? –

+0

@Marcos。感謝馬科斯,是的,我從底部的document.ready中調用它。 –

回答

1

我認爲你缺少一個關於參考點在JavaScript:

var search_form={}; 
search_form.widget_date_range = (function() { 
    // Whatever code here 

    // widget_controller variable references an empty object 
    var widget_controller = {}; // #A 
    var onDocumentReady = function() { 
    // Here you redefine widget_controller, 
    // but not the returned_object.widget_controller property 
    widget_controller = $(element_selector).dateRangeSlider(settings); #B 
    widget_controller.on("valuesChanged", onDataChange); 
    console.log(widget_controller); 
    }; 
    // Whatever here 
    return { 
    onDocumentReady: onDocumentReady, 
    // returned_objet.widget_controller references the empty object 
    widget_controller: widget_controller #C 
    }; 
})(); 

一種解決方案可能是:

... 
    return { 
    onDocumentReady: onDocumentReady, 
    get widget_controller() { 
     return widget_controller; #D 
    } 
    }; 
    ... 

的jsfiddle演示在這裏:https://jsfiddle.net/xgya3mzh/2/

編輯: (它似乎需要更多的解釋)

第一: 的{ get property() {} }語法與ES5,您可以在這裏MDN找到DOC:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

你可以用另一種語法完成同樣與ES3,這裏解釋:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineGetter(但使用此語法只有當你希望支持IE8及以下 - 我希望你不必)。

#A您聲明變量widget_controller並將其設置爲(幾乎)爲空的對象({}); (我說幾乎是因爲它仍然有一些具有一些繼承的方法和屬性的原型)。

#C您將對象字面量(將由閉包返回)的屬性widget_controller設置爲空對象的引用。

#B,這之後#C發生,重新定義了封閉的widget_controller,但你不重新定義的函數,它仍引用空對象的值返回對象的widget_controller。

在我的代碼中,在#D中,只要您訪問閉包返回的對象的屬性widget_controller,就會返回該閉包的相同widget_controller。

我希望它更清楚,雖然我不是很確定...

+1

我的天啊,它的作品!我的版本有什麼問題,親愛的拉魯伊斯?它不是一個典型的閉包,我的onDocumentReady函數中的widget_controller應該引用它的直接外部作用域,它將widget_controller定義爲一個空對象{}?爲什麼必須重新定義它?我現在正在撓頭。 –

+1

另外,你能否提供關於如何「獲取widget_controller()」部分的線索?我試着用Google搜索,但沒有找到任何相關的東西。非常感謝。 –

+0

有人能解釋一下爲什麼我的第一個版本不起作用的一點線索嗎?這對我來說似乎是一個完美的封閉。非常感謝。 –

相關問題