2

長年の .NET 開発者が、初めての Web アプリケーションを構築しています。デュランダル、ブリーズ、ノックアウトを使用しようとしていますが、これらはアーキテクチャ的に理解していると思います。しかし、これは、jQuery の基本的な概念のいくつかとともに外国に着陸したような気分になるという事実に変わりはありません。

Q でプロミスの概念を使用して、非同期プログラミングに問題があります。

var activate = function() {
    return ebodatacontext.getOrganizations(organizations);
};

ここで、API を介してエンティティからデータを取得するために Breeze データコンテキストが呼び出され、「組織」は ko.observableArray です。私のアプリでは、これはうまくいきます。

ただし、私の場合、ビューにはエンティティのリストが 2 つあるため、次のように Q でまとめた datacontext への 2 つの呼び出しが必要です。

var activate = function() {
    var promise =
        Q.all([
            ebodatacontext.getOrganizations(organizations),
            ebodatacontext.getUserRoles(userRoles)
        ]);
    return promise;
};

私が見る限り、これらの datacontext 呼び出しのいずれかが単独で機能し、ビューに正常にバインドされます。しかし、このようにそれらを IQ すると、最初のものだけが機能するように見えます。ここで基本的な何かが欠けているのではないかと心配しています。

ネットワーク トラフィックで、2 つのエンティティ セットに対して両方の API 呼び出しが行われていることがわかります。そして、良い結果がネットワーク経由で戻ってきます。

ただし、2 回目の呼び出しの ko.observable (userRoles) にはデータが含まれていないようです。Q配列でそれらの順序を入れ替えると、最初のものが機能します。ここで何かを怠ったように思えて、結合が早すぎるか何かです。

ここでの Q の使用が正しければ、他の場所でさらにデバッグを行う必要があると思います。前もって感謝します。

Breeze を使用した ebodatacontext は次のとおりです。

define([
    'durandal/system',
    'services/ebomodel',
    'config',
    'services/logger'],
    function (system, ebomodel, config, logger) {

        var EntityQuery = breeze.EntityQuery;
        var manager = configureBreezeManager();
        var orderBy = ebomodel.orderBy;
        var entityNames = ebomodel.entityNames;

        var getOrganizations = function(organizationsObservable, forceRemote) {
            if (!forceRemote) {
                var p = getLocal('Organizations', orderBy.Name);
                if (p.length > 0) {
                    organizationsObservable(p);
                    return Q.resolve();
                }
            }

            var query = EntityQuery.from('Organizations')
                //.orderBy(orderBy.Name)
                ;

            return manager.executeQuery(query)
                .then(querySucceeded)
                .fail(queryFailed);

            function querySucceeded(data) {
                if (organizationsObservable) {
                    organizationsObservable(data);
                }
                log('Retrieved [Organizations] from remote data source',
                    data, true);
            }
        };

        var getUserRoles = function(rolesObservable, forceRemote) {
            if (!forceRemote) {
                var p = getLocal('UserRoles', orderBy.Name);
                if (p.length > 0) {
                    rolesObservable(p);
                    return Q.resolve();
                }
            }

            var query = EntityQuery.from('UserRoles')
              //  .orderBy(orderBy.Name)
                ;

            return manager.executeQuery(query)
                .then(querySucceeded)
                .fail(queryFailed);

            function querySucceeded(data) {
                if (rolesObservable) {
                    rolesObservable(data);
                }
                log('Retrieved [UserRoles] from remote data source',
                    data, true);
            }
        };

        var cancelChanges = function() {
            manager.rejectChanges();
            log('Canceled changes', null, true);
        };

        var saveChanges = function() {
            return manager.saveChanges()
                .then(saveSucceeded)
                .fail(saveFailed);

            function saveSucceeded(saveResult) {
                log('Saved data successfully', saveResult, true);
            }

            function saveFailed(error) {
                var msg = 'Save failed: ' + error.message;
                logError(msg, error);
                error.message = msg;
                throw error;
            }
        };

        var primeData = function () {
         };

        var createOrganization = function() {
            return manager.createEntity(entityNames.organization);
        };

        var createUserRole = function() {
            return manager.createEntity(entityNames.role);
        };

        var hasChanges = ko.observable(false);

        manager.hasChangesChanged.subscribe(function(eventArgs) {
            hasChanges(eventArgs.hasChanges);
        });

        var ebodatacontext = {
            createOrganization: createOrganization,
            createUserRole: createUserRole,
            getOrganizations: getOrganizations,
            getUserRoles: getUserRoles,
            hasChanges: hasChanges,
            primeData: primeData,
            cancelChanges: cancelChanges,
            saveChanges: saveChanges
        };

        return ebodatacontext;

        //#region Internal methods        

        function getLocal(resource, ordering, includeNullos) {
            var query = EntityQuery.from(resource)
 //               .orderBy(ordering)
                ;
            //if (!includeNullos) {
            //    query = query.where('id', '!=', 0);
            //}
            return manager.executeQueryLocally(query);
        }

        function queryFailed(error) {
            var msg = 'Error retreiving data. ' + error.message;
            logger.logError(msg, error, system.getModuleId(ebodatacontext), true);
            throw error;
        }

        function configureBreezeManager() {
            breeze.NamingConvention.camelCase.setAsDefault();
            var mgr = new breeze.EntityManager(config.eboRemoteServiceName);
            ebomodel.configureMetadataStore(mgr.metadataStore);
            return mgr;
        }

        function log(msg, data, showToast) {
            logger.log(msg, data, system.getModuleId(ebodatacontext), showToast);
        }
        //#endregion
});
4

1 に答える 1