breeze observableArray binding - 属性是否可观察?

时间:2015-02-14 13:38:23

标签: breeze

我有一个viewModel,它由DoctorPrices的列表(foreach循环)组成,当点击列表中的某个项目时,它会在侧面打开一个CRUD表单。但是,当我更新CRUD上的值时,绑定到foreach的observableArray不会刷新? (尽管值正确地在DB中更新)

在我的数据访问模块中,我调用以下查询。

function getDoctorServices(doctorId) {
    var query = breeze.EntityQuery
         .from('DoctorPrices')
         .where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
    return manager.executeQueryLocally(query);
}

在我的viewmodel中,我有以下代码:

this.services = ko.computed(function() {
            return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});

使用foreach循环绑定服务(不在此处发布,因为代码很简单且可以正常工作

当我点击其中一个DoctorPrices时,它获取如下数据并将其放入一个可观察的数据中:

this.selectedPrice = function (data, event) {
            self.currentService(data);
            self.showEdit(true);

        };

然后我将selectPrice绑定到一个简单的表单,该表单上有要由用户修改的属性。然后我调用manager.SaveChanges()。

这会导致以下问题:值正在正确更新但是foreach中绑定的GUI /原始列表未更新?微风中的属性是不可观察的吗?使用这样的东西的最佳方法是什么。

我想到了一种解决方法,并使用以下内容更改代码:

doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
            self.services([]);
            self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
        });

但我觉得以这种方式清除阵列是草率的,而不是专门用长列表做事的正确方法。

有人可以指出我正确指导如何正确绑定observableArray属性以便更新它们吗?

我的VM组件的附加代码:

      function services() {
        var self = this;
        this.showForm = ko.observable(false);
        this.currentService = ko.observable();
        this.services = ko.observableArray(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
        this.title = ko.observable();


        doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
            self.services([]);
            self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
            self.showDetails(false);
        });


        this.show = function (value) {
            self.showForm(value);
        };


        this.showDetails = ko.observable(false);

        this.addNewService = function() {
            self.currentService(doctorServices.createService(doctorList.viewModel.instance.currentDoctorID()));
            console.log(self.currentService().entityAspect.entityState);
            self.showDetails(true);
        };

        this.showDelete = ko.computed(function() {
            if (self.currentService() == null)
                return false;
            else if (self.currentService().entityAspect.entityState.isDetached()) {
                self.title('Add new service');
                return false;
            } else {
                self.title('Edit service');
                return true;
            }
        });

        this.deleteService = function() {
            self.currentService().entityAspect.setDeleted();
            doctorServices.saveChanges();
            doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
        };

        this.closeDetails = function () {
            doctorServices.manager.rejectChanges();
            doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
            self.showDetails(false);
        };
        this.selectService = function (data, event) {
            self.currentService(data);
            self.showDetails(true);
        };
        this.saveChanges = function () {
            console.log(self.currentService().entityAspect.entityState);
            if (self.currentService().entityAspect.entityState.isDetached()) {
                doctorServices.attachEntity(self.currentService());
            }
            console.log(self.currentService().entityAspect.entityState);
            doctorServices.saveChanges();
            doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
            self.currentService.notifySubscribers();
            self.showDetails(true);
        };


    }
    return {
        viewModel: {
            instance: new services()
        },
        template: servicesTemplate,
    };

以下是我的微风数据类:

 define('data/doctorServices', ['jquery', 'data/dataManager', 'knockout','mod/medappBase', 'breeze', 'breeze.savequeuing'], function ($, manager, ko,base, breeze, savequeuing) {
var services = ko.observableArray([]);


return {
    attachEntity:attachEntity,
    getServices: getServices,
    services: services,
    manager:manager,
    getDoctorServices: getDoctorServices,
    getServiceById: getServiceById,
    createService:createService,
    hasChanges: hasChanges,
    saveChanges: saveChanges
};



function getServices() {
    var query = breeze.EntityQuery.from("DoctorPrices");
    return manager.executeQuery(query).then(function (data) {
        services(data.results);
    }).fail(function (data) {
        console.log('fetch failed...');
        console.log(data);
    });;
}



function getDoctorServices(doctorId) {
    var query = breeze.EntityQuery
         .from('DoctorPrices')
         .where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
    var set = manager.executeQueryLocally(query);

    return set;
}

function getServiceById(serviceId) {
    return manager.createEntity('DoctorPrice', serviceId);
    //return manager.getEntityByKey('DoctorPrice', serviceId);
}

function handleSaveValidationError(error) {
    var message = "Not saved due to validation error";
    try { // fish out the first error
        var firstErr = error.innerError.entityErrors[0];
        message += ": " + firstErr.errorMessage;
        base.addNotify('error', 'Could not save.', message);
    } catch (e) { /* eat it for now */ }
    return message;
}

function hasChanges() {
    return manager.hasChanges();
}

function attachEntity(entity) {
    manager.addEntity(entity);
}

function createService(doctorId) {
    return manager.createEntity('DoctorPrice', { DoctorPricingID: breeze.core.getUuid(), DoctorID:doctorId }, breeze.EntityState.Detached);

};


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

    function saveSucceeded(saveResult) {
        base.addNotify('success', 'Saved.', 'Your updates have been saved.');
    }

    function saveFailed(error) {
        var reason = error.message;
        var detail = error.detail;

        if (error.innerError.entityErrors) {
            reason = handleSaveValidationError(error);
        } else if (detail && detail.ExceptionType &&
            detail.ExceptionType.indexOf('OptimisticConcurrencyException') !== -1) {
            // Concurrency error 
            reason =
                "Another user, perhaps the server, " +
                "may have deleted one or all of the settings." +
                " You may have to restart the app.";
        } else {
            reason = "Failed to save changes: " + reason +
                     " You may have to restart the app.";
        }
        console.log(error);
        console.log(reason);
    }
}

});

请注意,这是我对数据类和VM的尝试。目前我非常依赖清除数组([])并使用notifySubscribers来刷新阵列 :(

2 个答案:

答案 0 :(得分:0)

我打赌你在某个地方错过了一个观察点。我无法告诉你,因为你不断地从一个属性跳到另一个没有显示定义的属性。

例如,我不知道您如何定义this.currentService

我对此感到困惑:

this.services = ko.computed(function() {
        return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});

为什么是ko.computed?为什么不把它an observable array

self.service = ko.observableArray();

// ... later replace the inner array in one step ...
self.service(doctorServices.getDoctorServices(
    doctorList.viewModel.instance.currentDoctorID()));

我敦促您遵循可观察性的追踪,确信您的Breeze实体属性确实是可观察的。

答案 1 :(得分:0)

 vm.selectedPrice  = ko.dependentObservable(function () {

       return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());


    }, vm);

vm是你应用绑定的模型,试试这个它会起作用。