在onAfterRender函数中未定义的knockout视图模型属性

时间:2011-10-20 17:00:33

标签: javascript knockout.js

我有一个类似下面的视图模型,当Knockout触发onAfterRender然后执行viewmodel(也称为onAfterRender)中的函数但是this.gridColumns的值,this.gridOptions未定义是否仍有解决方法?我宁愿保留对象功能而不是使用对象文字。

我像这样创建我的viewModel:

var model = new i2owater.viewmodels.AlarmsForViewModel(somedata);

并调用ko.applyBindings(model);

这是我的观点模型:

viewModel = function (serverData) {
var alarmGrid = {};

function onAfterRender() {
    var that = this;
    this.alarmGrid = new i2owater.Slickgrid();

    // this.gridColumns and this.gridOptions are both undefined
    this.alarmGrid.setupGrid("#alarmsGrid", [], this.gridColumns, this.gridOptions);
};

return {
    data: data,
    tabs: tabs,
    selectedPriority: selectedPriority,
    company: company,
    zone: zone,
    rows: rows,
    alarmPeriod: alarmPeriod,
    //alarmGrid: alarmGrid,
    gridColumns: [{ id: "id", name: "ID", field: "id", sortable: true },
        { id: "date", name: "Date", field: "date", sortable: true },
        { id: "description", name: "Description", field: "description"}],
    gridOptions: {
        editable: true,
        enableCellNavigation: true,
        asyncEditorLoading: true,
        forceFitColumns: false,
        topPanelHeight: 25,
        rowHeight: 40
    }
    onAfterRender: onAfterRender
};

};

1 个答案:

答案 0 :(得分:1)

在这种情况下,有几种方法可以确保this正确无误。

一个选项是创建一个result变量,将函数绑定到该变量,然后返回result

var result = {
    data: data,
    tabs: tabs,
    selectedPriority: selectedPriority,
    company: company,
    zone: zone,
    rows: rows,
    alarmPeriod: alarmPeriod,
    //alarmGrid: alarmGrid,
    gridColumns: [{ id: "id", name: "ID", field: "id", sortable: true },
        { id: "date", name: "Date", field: "date", sortable: true },
        { id: "description", name: "Description", field: "description"}],
    gridOptions: {
        editable: true,
        enableCellNavigation: true,
        asyncEditorLoading: true,
        forceFitColumns: false,
        topPanelHeight: 25,
        rowHeight: 40
    }
};

result.onAfterRender = onAfterRender.bind(result);

return result;

否则,您可以像这样构建它,而不是返回匿名对象文字:

viewModel = function (serverData) {
    var alarmGrid = {};

    function onAfterRender() {
        var that = this;
        this.alarmGrid = new i2owater.Slickgrid();

        // this.gridColumns and this.gridOptions are both undefined
        this.alarmGrid.setupGrid("#alarmsGrid", [], this.gridColumns, this.gridOptions);
    };

    this.data = data;
    this.tabs = tabs;
    this.selectedPriority = selectedPriority;
    this.company = company;
    this.zone = zone;
    this.rows = rows;
    this.alarmPeriod = alarmPeriod;
    this.gridColumns = [{ id: "id", name: "ID", field: "id", sortable: true },
            { id: "date", name: "Date", field: "date", sortable: true },
            { id: "description", name: "Description", field: "description"}];
    this.gridOptions = {
        editable: true,
        enableCellNavigation: true,
        asyncEditorLoading: true,
        forceFitColumns: false,
        topPanelHeight: 25,
        rowHeight: 40
    };
    this.onAfterRender = onAfterRender.bind(this);
};

或使用类似于KO 1.3 ko.utils.extend的扩展函数来扩展当前this,如:

viewModel = function (serverData) {
    var alarmGrid = {};

    function onAfterRender() {
        this.alarmGrid = new i2owater.Slickgrid();
        this.alarmGrid.setupGrid("#alarmsGrid", [], this.gridColumns, this.gridOptions);
    };

    ko.utils.extend(this, {
        data: data,
        tabs: tabs,
        selectedPriority: selectedPriority,
        company: company,
        zone: zone,
        rows: rows,
        alarmPeriod: alarmPeriod,
        //alarmGrid: alarmGrid,
        gridColumns: [{ id: "id", name: "ID", field: "id", sortable: true },
            { id: "date", name: "Date", field: "date", sortable: true },
            { id: "description", name: "Description", field: "description"}],
        gridOptions: {
            editable: true,
            enableCellNavigation: true,
            asyncEditorLoading: true,
            forceFitColumns: false,
            topPanelHeight: 25,
            rowHeight: 40
        }
        onAfterRender: onAfterRender.bind(this)
    });
};

此外,使用bind的替代方法是在构造函数的开头执行var self = this;,然后在onAfterRender函数中使用self