0

我们使用 jquery 和 requirejs 来创建一个像这样的“viewmodel”:

define('vm.inkoopfactuurAanleveren',
['jquery', 'underscore', 'ko', 'datacontext', 'router', 'messenger', 'config', 'store'],
function ($, _, ko, datacontext, router, messenger, config, store) {
    var
        isBusy = false,
        isRefreshing = false,
        inkoopFactuur = { factuurNummer: ko.observable("AAA") },           
        activate = function (routeData, callback) {
            messenger.publish.viewModelActivated({ canleaveCallback: canLeave });
            getNewInkoopFactuurAanleveren(callback);              
            var restricteduploader = new qq.FineUploader({                    
                element: $('#restricted-fine-uploader')[0],
                request: {
                    endpoint: 'api/InkoopFactuurAanleveren',
                    forceMultipart: true
                },
                multiple: false,                 
                failedUploadTextDisplay: {
                    mode: 'custom',
                    maxChars: 250,
                    responseProperty: 'error',
                    enableTooltip: true
                },
                text: {
                    uploadButton: 'Click or Drop'
                },
                showMessage: function (message) {                        
                    $('#restricted-fine-uploader').append('<div class="alert alert-error">' + message + '</div>');
                },
                debug: true,

                callbacks: {
                    onComplete: function (id, fileName, responseJSON) {
                        var response = responseJSON;
                    },
                }
            });
        },

       invokeFunctionIfExists = function (callback) {
           if (_.isFunction(callback)) {
               callback();
           }
       },

        loaded = function (factuur) {
            inkoopFactuur = factuur;
            var ids = config.viewIds;
            ko.applyBindings(this, getView(ids.inkoopfactuurAanleveren)); /*<----- THIS = OUT OF SCOPE!*/                /
        },

        bind = function () { },

        saved = function (success) {
            var s = success;
        },

        saveCmd = ko.asyncCommand({
            execute: function (complete) {
                $.when(datacontext.saveNewInkoopFactuurAanleveren(inkoopFactuur))
                        .then(saved).always(complete);
                return;
            },
            canExecute: function (isExecuting) {
                return true;
            }
        }),

        getView = function (viewName) {
            return $(viewName).get(0);
        },

        getNewInkoopFactuurAanleveren = function (callback) {
            if (!isRefreshing) {
                isRefreshing = true;                    
                $.when(datacontext.getNewInkoopFactuurAanleveren(dataOptions(true))).then(loaded).always(invokeFunctionIfExists(callback));
                isRefreshing = false;
            }

        },

        dataOptions = function (force) {
            return {
                results: inkoopFactuur,
                // filter: sessionFilter,
                //sortFunction: sort.sessionSort,
                forceRefresh: force
            };
        },

        canLeave = function () {
            return true;
        },            

        forceRefreshCmd = ko.asyncCommand({
            execute: function (complete) {
                //$.when(datacontext.sessions.getSessionsAndAttendance(dataOptions(true)))
                //    .always(complete);
                complete;
            }
        }),                        

        init = function () {
           // activate();
            // Bind jQuery delegated events
            //eventDelegates.sessionsListItem(gotoDetails);
            //eventDelegates.sessionsFavorite(saveFavorite);

            // Subscribe to specific changes of observables
            //addFilterSubscriptions();
        };

        init();

    return {
        activate: activate,
        canLeave: canLeave,
        inkoopFactuur: inkoopFactuur,
        saveCmd: saveCmd,
        forceRefreshCmd: forceRefreshCmd,
        bind: bind,
        invokeFunctionIfExists: invokeFunctionIfExists                  
    };
});

在“加载”方法的行ko.applyBindings(this, getView(ids.inkoopfactuurAanleveren));中,“this”关键字不引用“viewmodel”对象。“self”关键字似乎是指在多个“viewmodels”上找到的方法的组合。saveCmd 属性是通过敲除绑定的,但由于找不到它而给出错误。

ko.applyBindings 如何获得对视图模型的正确引用?换句话说,我们需要用什么来替换applyBindings 中的'this' 关键字。

我想你可以“要求”requirejs 给我们带有标识符“vm.inkoopfactuurAanleveren”的 ealiers 实例化对象,但我不知道如何。

4

2 回答 2

1

只需在该行之后使用该行function ($, _, ko, datacontext, router, messenger, config, store) {

var me = this;

然后在你需要参考的地方使用我

*注意这可能不是最好的方法,但这就是我不这样做的方式 - cntrl 下的所有内容

于 2012-11-30T11:50:06.500 回答
1

您遇到的问题不是来自 RequireJS,而是来自您创建视图模型的方式以及您没有注意函数中的“this”是什么这一事实。

通过阅读您的代码,我可以告诉您加载方法中的“this”是一个看起来像这样的 jQuery Deferred 对象
Object,
always: function (){ ... },
done: function (){ ... },
fail: function (){ ... },

这个简短的教程将让您了解问题所在。 http://dailyjs.com/2012/06/18/js101-this/

要使这项工作正常进行,只要您像这样调用 activate ,请在您的函数中viewModel.activate()更改.then(loaded)为。这应该使函数中的 this 成为 viewmodel 对象。.then($.proxy(loaded, this))getNewInkoopFactuurAanleverenloaded

但是,您应该决定一种更好的方法来在应用程序中构建可重用的模块或类,并在这些 RequireJS 定义方法中创建构造函数将是一个好的开始。

define([ "jquery" ], function ($) {  
    var User = function (username, password) {  
        this.username = username;  
        this.password = password;  
        this.isActive = false;
    }  

    User.prototype.activate = function () {  
        this.isActive = true;  
    };  

    return User;  
}

请注意,RequireJS 只会调用此方法一次,这就是为什么最好创建一个构造函数,然后在您需要该类型的新对象时以这种方式使用它。

var user = new User("user1", "pass");  
user.activate();  

在此处查看有关如何创建简单类的一些示例。 http://weblogs.asp.net/dwahlin/archive/2011/12/19/using-the-javascript-prototype-property-to-structure-and-extend-code.aspx

于 2012-12-02T22:50:53.580 回答