onAfterRender 函数中未定义的剔除视图模型属性

发布于 2024-12-10 18:40:35 字数 1319 浏览 0 评论 0原文

我有一个如下所示的视图模型,当 Knockout 触发 onAfterRender 时,将执行视图模型中的函数(也称为 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
};

};

I have a view model something like below, when onAfterRender is fired by Knockout then the function in the viewmodel (also called onAfterRender) is executed but the values for this.gridColumns, this.gridOptions are undefined is there anyway to fix this? I would prefere to keep the object function rather than using an object literal.

I create my viewModel like this:

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

and call ko.applyBindings(model);

this is my view 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
};

};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那支青花 2024-12-17 18:40:35

有多种方法可以确保 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; ,然后使用 self 在 onAfterRender 函数内。

There are a several ways that you could ensure that this is correct in this situation.

One option would be to create a result variable, bind your function to that variable, then return 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;

Otherwise, rather than returning an anonymous object literal, you can build it like this:

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);
};

or use an extend function like in KO 1.3 ko.utils.extend to extend the current this like:

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)
    });
};

Also, an alternative to using bind would be to do a var self = this; at the beginning of the constructor function, then use self inside the onAfterRender function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文