0

我正在尝试为我的应用程序创建一个基本视图模型,但我正在努力访问基本视图模型的上下文。

这是我的基本视图模型:

define(["config", 'services/logger'], function (config, logger) {
    'use strict';
    var
    app = require('durandal/app'),
    baseViewModel = function () {
        this.items = ko.observableArray();
        this.title = ko.observable();
        this.selectedItem = ko.observable();
    };
    baseViewModel.prototype = (function () {
        var
        populateCollection = function (initialData, model) {
            var self = this;
            if (_.isEmpty(self.items())) {
                ko.utils.arrayForEach(initialData, function (item) {
                    // self here works for all extending modules such as users
                    self.items.push(new model(item));
                });
            }
        },
        deleteItem = function (item) {
            // "this" here same as prototype gives me window object :(
            // so removing never happes
            this.items.remove(item);
            logger.log(config.messages.userMessages.confirmDeleted(item.Name()), {}, '', true);
        },
        confirmDelete = function (item) {
            var
            userMessage = config.messages.userMessages.confirmDelete(item.Type(), item.Name()),
            negation = config.confirmationModalOptions.negation,
            affirmation = config.confirmationModalOptions.affirmation;

            app.showMessage(userMessage, 'Deleting ' + item.Type(), [affirmation, negation]).then(
                function (dialogResult) {
                    dialogResult === affirmation ? deleteItem(item) : false;
                });
        };
        return {
            populateCollection: populateCollection,
            confirmDelete: confirmDelete,
            deleteItem: deleteItem
        }
    })();
    return baseViewModel;
});

我使用这个不工作的东西的一个例子是:

define(['services/logger', 'models/user', 'viewmodels/baseviewmodel', 'services/dataservice'], function (logger, user, baseviewmodel, dataservice) {
    var
    users = new baseviewmodel();
    users.title('Users')
    users.searchTerm = ko.observable().extend({ persist: users.title() + '-searchterm' });
    users.activate = function () {
        this.populateCollection(dataservice.getUsers, user.model);
    }
    return users;
});

使用populateCollection. confirmDelete也可以在模板中正确绑定,这可能是由于不需要上下文但deleteItem需要上下文以便它可以访问items和调用remove它。

我如何正确地访问this它的上下文,baseViewModel 以便我可以使用这种模式在我的方法中轻松地引用它?

非常感谢

4

1 回答 1

1

编辑:看起来可能this在deleteItem中没有正确绑定,因为它在confirmDelete内部的回调中被调用。所以在你的原始模型上试试这个片段

    confirmDelete = function (item) {
        var self=this,
        userMessage = config.messages.userMessages.confirmDelete(item.Type(), item.Name()),
        negation = config.confirmationModalOptions.negation,
        affirmation = config.confirmationModalOptions.affirmation;

        app.showMessage(userMessage, 'Deleting ' + item.Type(), [affirmation, negation]).then(
            function (dialogResult) {
                dialogResult === affirmation ? self.deleteItem.call(self,item) : false;
            });
    };

orrr,我的另一个解决方案。

我以前从未使用过“揭示原型模式”,所以这里是如何在不遵循我们都不理解的模式的情况下做到这一点:)

我将所有内容声明为我的 viewmodel 和 use 的属性,var self = this这样我的所有代码的作用就非常明确了。这是您的基本视图模型,已重写。如果您的所有视图模型逻辑都封装在视图模型中,并且视图模型在构造函数/函数定义中声明其依赖关系,这通常会很有帮助。

baseViewModel = function (dataService,userModel) {
    var self = this;
    self.items = ko.observableArray();
    self.title = ko.observable();
    self.searchTerm = ko.observable().extend({ persist: self.title() + '-searchterm' });
    self.selectedItem = ko.observable();

    self.populateCollection = function (initialData, model) {
        if (_.isEmpty(self.items())) {
            ko.utils.arrayForEach(initialData, function (item) {
                // self here works for all extending modules such as users
                self.items.push(new model(item));
            });
        }
    };

    self.activate = function () {
        this.populateCollection(dataservice.getUsers, userModel);
    }

    self.deleteItem = function (item) {
        // "this" here same as prototype gives me window object :(
        // so removing never happes
        self.items.remove(item);
        logger.log(config.messages.userMessages.confirmDeleted(item.Name()), {}, '', true);
    };

    self.confirmDelete = function (item) {
        var
        userMessage = config.messages.userMessages.confirmDelete(item.Type(), item.Name()),
        negation = config.confirmationModalOptions.negation,
        affirmation = config.confirmationModalOptions.affirmation;

        app.showMessage(userMessage, 'Deleting ' + item.Type(), [affirmation, negation]).then(
            function (dialogResult) {
                dialogResult === affirmation ? self.deleteItem(item) : false;
            });
    };
};

请注意,因为我还将您的依赖项移到了 viewmodel 构造函数中,所以现在您的初始化代码如下所示:

define(['services/logger', 'models/user', 'viewmodels/baseviewmodel', 'services/dataservice'], function (logger, user, baseviewmodel, dataservice) {
    var users = new baseviewmodel(dataservice,user.model);
    users.title('Users')
    return users;
});
于 2013-10-23T21:28:30.147 回答