0

jqueryとrequirejsを使用して、次のような「ビューモデル」を作成します。

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

'loaded'メソッドの行ko.applyBindings(this, getView(ids.inkoopfactuurAanleveren));で、'this'キーワードは'viewmodel'オブジェクトを参照していません。「self」キーワードは、複数の「viewmodels」で見つかったメソッドの組み合わせを参照しているようです。saveCmdプロパティはノックアウトを介してバインドされていますが、見つからないためエラーが発生します。

ko.applyBindingsはどのようにしてビューモデルへの正しい参照を取得できますか?言い換えると、applyBindingsの「this」キーワードを何に置き換える必要がありますか。

requirejsに、識別子が「vm.inkoopfactuurAanleveren」のealiersインスタンス化オブジェクトを提供するように「依頼」できると思いますが、その方法がわかりません。

4

2 に答える 2

1

発生している問題は、RequireJSに起因するのではなく、ビューモデルを作成する方法と、関数内の「これ」に注意を払っていないという事実に起因します。

コードを読むと、ロードされたメソッドの「this」は、次のようなjQueryDeferredオブジェクトであることがわかります。
Object,
always: function (){ ... },
done: function (){ ... },
fail: function (){ ... },

この短いチュートリアルでは、何がうまくいかないかについて説明します。 http://dailyjs.com/2012/06/18/js101-this/

これを機能させるには、そのようにactivateを呼び出す場合は、関数をviewModel.activate()に変更.then(loaded).then($.proxy(loaded, this))ますgetNewInkoopFactuurAanleveren。これにより、loaded関数内のこれがビューモデルオブジェクトになります。

ただし、アプリケーションで再利用可能なモジュールまたはクラスを構築するためのより良い方法を決定する必要があり、それらの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はこのメソッドを1回だけ呼び出すため、コンストラクター関数を作成し、そのタイプの新しいオブジェクトが必要な場合はいつでもその方法で使用することをお勧めします。

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 に答える
1

行の直後にこの行を使用するだけですfunction ($, _, ko, datacontext, router, messenger, config, store) {

var me = this;



そして、あなたが参照する必要があるところならどこでも私を使ってください*これは最善の方法ではないかもしれませんが、これは私がそれをしない方法です-cntrlの下のすべて

于 2012-11-30T11:50:06.500 に答える