Breeze 不保存已编辑的新实体

Breeze does not save new entitites that has been edited

我有一个配置页面,我可以在其中创建、编辑和删除不同类型的内容。现在问题就出现了,当你创建一个新实体的时候,选择"EDIT"也是一样的。然后它不会发现有变化,唉,当我尝试保存时没有任何反应。

请记住保存和删除作品,以及编辑旧实体。旧的我的意思是系统已经刷新了一次所有内容。我认为必须是带有临时 ID 或缓存的东西?

方法 运行 将所有内容都设置为 editCompanyType() 然后 运行s Save()

精简版

当我创建一个新实体时,然后选择编辑它它不会保存新编辑的值 尽管值本身会在屏幕上更新。

从我的 ViewModel 我 运行 创建一个新实体时

var companyTypeTemp = configunitofwork.configcompanytypesrepository.createEntity();

正在加载我的模式并返回结果。并在需要时保存。

 var diag = new genericModal("", 'företagstyp');

        diag.viewUrl = 'views/config/genericModal';

        app.showDialog(diag).then(function (diagResult) {
            if (diagResult === 'update') {
                companyTypeTemp.company_type_text = diag.generic_type;
                Save();
            } else {
                logger.log("Du gjorde inga ändringar!", null, "panel", true);
            }
        });

保存在此处。

    function Save() {
        if (!configunitofwork.hasChanges()) {

            return true;

        }
        configunitofwork.commit()
            .then(function () {
                refreshCompanyTypes(companyTypes);
                logger.logSuccess("Företagstypen sparades!", null, "panel", true);
            });

        return true;
    }

现在,当我尝试编辑新创建的实体时失败了,它没有获取任何更改..?

我将我的操作绑定到视图

  var bindAction = function (view) {
        $(view).on('click', '.editCompanyType', function () {
            var company_type = ko.dataFor(this);
            editCompanyType(company_type);
        });

    };

所以当我点击我的实体时,我将运行我的编辑方法

    var editCompanyType = function (company_type) {

        var diag = new genericModal(company_type.company_type_text, 'företagstyp');
        diag.viewUrl = 'views/config/genericModal';
        app.showDialog(diag).then(function (diagResult) {
            if (diagResult === 'update') {
                //update
                Save();
            } else if (diagResult === 'delete') {
                //delete
                deleteCompanyType(company_type);
            }
            else {
                logger.log("Du gjorde inga ändringar!", null, "panel", true);
            }
        });
    };

这将依次加载我的模态,它是通用的并采用文本数据以及表示当前类型上下文的字符串。

   var genericModal = function (genericType, genericnametype) {

        this.generic_type = ko.observable(genericType);
        this.placeholder_text = 'Skriv din ' + genericnametype;
        this.modal_title = ko.observable('Lägg till ' + genericnametype);
        //Uppercase machine
        this.modal_toastr_text = genericnametype;
        this.modal_header = genericnametype[0].toUpperCase() + genericnametype.slice(1);
        this.update_button_text = ko.observable('Lägg till ' + genericnametype);
        this.delete_button_text = ko.observable('Ta bort ' + genericnametype);
        this.deleteAllowed = ko.observable(false);
        this.update_icon_class = 'fa fa-gear';
        this.delete_icon_class = 'fa fa-eject';

        if (genericType != "") {
            this.generic_type = genericType;
            this.modal_title = ko.observable('Uppdatera ' + genericnametype);
            this.update_button_text = ko.observable('Uppdatera ' + genericnametype);
            this.deleteAllowed(true);
        }
    };

我绑定this.generic_type错了吗?

在HTML中是这样绑定的

data-bind="value: generic_type,attr: {placeholder: placeholder_text}">

JS - 视图模型

define(['durandal/app', 'services/config/configunitofwork', 'services/errorhandler', 'services/logger', 'model/config/genericModal'],
function (app, configunitofwork, errhandler, logger, genericModal) {

    var companyTypes = ko.observableArray();
    var configunitofwork = configunitofwork.create();

    var attached = function (view) {
        refreshCompanyTypes(companyTypes);
        bindAction(view);
    };

    var bindAction = function (view) {
        $(view).on('click', '.editCompanyType', function () {
            var company_type = ko.dataFor(this);
            editCompanyType(company_type);
        });

    };

    function refreshCompanyTypes(companyTypes) {
        var companyTypesRefresh = configunitofwork.configcompanytypesrepository.all()
                               .then(function (companyTypesRefresh) {
                                   companyTypes(companyTypesRefresh);
                               });
    }

    function Save() {
        if (!configunitofwork.hasChanges()) {
            return true;

        }
        configunitofwork.commit()
            .then(function () {
                refreshCompanyTypes(companyTypes);
                logger.logSuccess("Företagstypen sparades!", null, "panel", true);
            });

        return true;
    }

    var addCompanyType = function () {
        var companyTypeTemp = configunitofwork.configcompanytypesrepository.createEntity();
        var diag = new genericModal("", 'företagstyp');

        diag.viewUrl = 'views/config/genericModal';

        app.showDialog(diag).then(function (diagResult) {
            if (diagResult === 'update') {
                companyTypeTemp.company_type_text = diag.generic_type;
                Save();
            } else {
                logger.log("Du gjorde inga ändringar!", null, "panel", true);
            }
        });
    };

    var editCompanyType = function (company_type) {

        var diag = new genericModal(company_type.company_type_text, 'företagstyp');
        diag.viewUrl = 'views/config/genericModal';
        app.showDialog(diag).then(function (diagResult) {
            if (diagResult === 'update') {
                //update
                companyTypes.company_type_text = diagResult.generic_type;
                Save();
            } else if (diagResult === 'delete') {
                //delete
                deleteCompanyType(company_type);
            }
            else {
                logger.log("Du gjorde inga ändringar!", null, "panel", true);
            }
        });
    };

    var deleteCompanyType = function (company_type) {
        configunitofwork.configcompanytypesrepository.delete(company_type);
        configunitofwork.commit()
            .then(function () {
                refreshCompanyTypes(companyTypes);
               /// logger.logSuccess("Företagstypen: " + company_type.company_type_text + " togs bort!", null, null, true);
            })
        //.fail(self.handleError);
    };



    var viewModel = {
        attached:        attached,
        companyTypes:    companyTypes,
        addCompanyType:  addCompanyType, 
        editCompanyType: editCompanyType
    }

    return viewModel;
});

模态JS

define(['durandal/app', 'plugins/dialog', 'knockout', 'jquery', 'services/logger'],
function (app, dialog, ko, $, logger) {

    var companyTypesModal = function (companyType) {
        this.company_type = ko.observable(companyType);

        this.modal_title = ko.observable('Lägg till företagstyp');
        this.update_button_text = ko.observable('Lägg till företagstyp');
        this.delete_button_text = ko.observable('Ta bort företagstyp');
        this.deleteAllowed = ko.observable(false);
        this.update_icon_class = 'fa fa-gear';
        this.delete_icon_class = 'fa fa-eject';

        if (companyType != "") {
            this.company_typen = companyType
            this.company_type =  ko.computed(function () {
                return $.trim(this.company_typen());
            }, this);
            this.modal_title = ko.observable('Uppdatera företagstyp');
            this.update_button_text = ko.observable('Uppdatera företagstyp');
            this.deleteAllowed(true);
        }
    };

    companyTypesModal.prototype.closeModal = function () {
        dialog.close(this, 'close');
    };

    companyTypesModal.prototype.updatecompanyTypesModal = function () {
        var me = this;
        dialog.close(me, 'update');
    };

    companyTypesModal.prototype.deletecompanyTypesModal = function () {

        var me = this;
        app.showMessage("Är du säker på att du vill ta bort denna företagstyp?", "Ta bort", ['Nepp', 'Ja'])
            .then(function (selectedOption) {
                if (selectedOption === "Ja") {
                    dialog.close(me, 'delete');
                }
            });
    };

    return companyTypesModal;
});

HTML 主要

<div class="page-header">
 <button class="btn" data-bind="click: addCompanyType"><i class="icon-user">    </i>&nbsp;&nbsp;Lägg till företagstyp!</button>
 </div>
 <h4>&nbsp;&nbsp;Företagstyper</h4>
 <div class="row mart5" data-bind="foreach: companyTypes">
 <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
    <div class="row">
        <div class="col-xs-3">
            <a class="thumbnail">
                <img src="/Content/icons/icon_user.png" />
            </a>
        </div>
        <div class="col-xs-9 h-vcenter-parent">
            <div class="h-vcenter-child">
                <h4 data-bind="text: company_type_text"></h4>
                <div class="btn-group pull-right">
                    <button class="btn dropdown-toggle" data-toggle="dropdown">Alternativ&nbsp;<span class="caret"></span></button>
                    <ul class="dropdown-menu">
                        <li><a style="cursor: pointer;" class="editCompanyType">Redigera företagstyp</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

HTML - 模态

<div id="edited">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true" data-bind="click: closeModal">&times;</button>
            <h1 class="modal-title" data-bind="text: modal_title"></h1>
        </div>
        <div class="modal-body">
            <div class="form-group">
                <div class="page-header">
                    <h2><i class="fa fa-pencil-square"></i>Företagstyp</h2>
                </div>
                <div class="row">
                    <div class="col-xs-9 col-sm-8 col-md-9 col-lg-10">
                        <input class="form-control mart2" id="company_type" name="company_type" type="text" data-bind="value: company_type_text" placeholder="Skriv företagstypen">
                        <span class="help-block"><small>Här lägger du till en företagstyp(återförsäljare, vanlig kund osv. v1)</small></span>

                    </div>
                </div>
                <div>
                    <a href="#" class="btn btn-primary" data-bind="click: updatecompanyTypesModal"><i data-bind="css: update_icon_class"></i>&nbsp;<span data-bind="text: update_button_text"></span>  </a>
                    <a href="#" class="btn btn-primary" data-bind="click: deletecompanyTypesModal, visible: deleteAllowed"><i data-bind="css: delete_icon_class"></i>&nbsp;<span data-bind="text: delete_button_text"></span>  </a>
                </div>
            </div>
        </div>
    </div>
</div>

JS - UNITOFWORK

define(['durandal/app', 'services/routeconfig',    'services/config/configmanagerprovider', 'services/repository', 'services/config/configcompanytypesrepository', 'services/config/configcustomertypesrepository', 'services/config/configgroupproductrepository', 'services/config/configgroupwarrantyrepository', 'services/config/configorderstatusrepository', 'services/config/configordertypefilterrepository', 'services/config/configordertyperepository', 'services/config/configordertypewarrantyrepository', 'services/config/configproductgrouprepository', 'services/config/configproducttyperepository', 'services/config/configreclaimrepository', 'services/config/configstorerepository', 'services/config/configwarrantyrepository'],
function (app, routeconfig, configmanagerprovider, repository, configcompanytypesrepository, configcustomertypesrepository, configgroupproductrepository, configgroupwarrantyrepository, configorderstatusrepository, configordertypefilterrepository, configordertyperepository, configordertypewarrantyrepository, configproductgrouprepository, configproducttyperepository, configreclaimrepository, configstorerepository, configwarrantyrepository) {

    var refs = {};

    /**
    * AdminUnitOfWork ctor
    * @constructor
    */
    var ConfigUnitOfWork = (function () {

        var configUnitOfWork = function () {
            var provider = configmanagerprovider.create();

            /**
            * Has the current AdminUnitOfWork changed?
            * @method
            * @return {bool}
            */
            this.hasChanges = function () {
                return provider.manager().hasChanges();
            };

            /**
            * Commit changeset
            * @method
            * @return {promise}
            */
            this.commit = function () {
                var saveOptions = new breeze.SaveOptions({ resourceName: routeconfig.saveAdminChangesUrl });

                return provider.manager().saveChanges(null, saveOptions)
                    .then(function (saveResult) {
                        app.trigger('saved', saveResult.entities);
                    });
            };

            /**
            * Rollback changes
            * @method
            */
            this.rollback = function () {
                provider.manager().rejectChanges();
            };

            this.configcompanytypesrepository =   configcompanytypesrepository.create(provider, "Company_Type", routeconfig.configCompanyTypes);
            this.configcustomertypesrepository = configcustomertypesrepository.create(provider, "Customer_Type", routeconfig.configCustomerTypes);
            this.configgroupproductrepository = configgroupproductrepository.create(provider, "GroupProduct", routeconfig.configGroupProducts);
            this.configgroupwarrantyrepository = configgroupwarrantyrepository.create(provider, "GroupWarranty", routeconfig.configGroupWarranties);
            this.configorderstatusrepository = configorderstatusrepository.create(provider, "Order_Status", routeconfig.configOrderStatuses);
            this.configordertypefilterrepository = configordertypefilterrepository.create(provider, "OrderTypeFilter", routeconfig.configOrderTypeFilters);
            this.configordertyperepository = configordertyperepository.create(provider, "Order_Type", routeconfig.configOrderTypes);
            this.configordertypewarrantyrepository = configordertypewarrantyrepository.create(provider, "OrderTypeWarranty", routeconfig.configOrderTypeWarranties);
            this.configproductgrouprepository = configproductgrouprepository.create(provider, "Product_Group", routeconfig.configProductGroups);
            this.configproducttyperepository = configproducttyperepository.create(provider, "Product_Type", routeconfig.configProductTypes);
            this.configreclaimrepository = configreclaimrepository.create(provider, "Reclaim", routeconfig.configReclaims);
            this.configstorerepository = configstorerepository.create(provider, "Store", routeconfig.configStores);
            this.configwarrantyrepository = configwarrantyrepository.create(provider, "Warranty", routeconfig.configWarranties);
        };

        return configUnitOfWork;
    })();

    var SmartReference = (function () {

        var ctor = function () {
            var value = null;

            this.referenceCount = 0;

            this.value = function () {
                if (value === null) {
                    value = new ConfigUnitOfWork();
                }

                this.referenceCount++;
                return value;
            };

            this.clear = function () {
                value = null;
                this.referenceCount = 0;

                clean();
            };
        };

        ctor.prototype.release = function () {
            this.referenceCount--;
            if (this.referenceCount === 0) {
                this.clear();
            }
        };

        return ctor;
    })();

    return {
        create: create,
        get: get
    };

    /**
     * Get a new AdminUnitOfWork instance
     * @method
     * @return {AdminUnitOfWork}
    */
    function create() {
        return new ConfigUnitOfWork();
    }

    /**
     * Get a new AdminUnitOfWork based on the provided key
     * @method
     * @param {int/string} key - Key used in the reference store
     * @return {promise}
    */
    function get(key) {
        if (!refs[key]) {
            refs[key] = new SmartReference();
        }

        return refs[key];
    }

    /**
     * Delete references
     * @method         
    */
    function clean() {
        for (key in refs) {
            if (refs[key].referenceCount == 0) {
                delete refs[key];
            }
        }
    }
});

JS -ManagerProvider

define(['durandal/app', 'services/routeconfig', 'services/config/configmanagerprovider', 'services/repository', 'services/config/configcompanytypesrepository', 'services/config/configcustomertypesrepository', 'services/config/configgroupproductrepository', 'services/config/configgroupwarrantyrepository', 'services/config/configorderstatusrepository', 'services/config/configordertypefilterrepository', 'services/config/configordertyperepository', 'services/config/configordertypewarrantyrepository', 'services/config/configproductgrouprepository', 'services/config/configproducttyperepository', 'services/config/configreclaimrepository', 'services/config/configstorerepository', 'services/config/configwarrantyrepository'],
function (app, routeconfig, configmanagerprovider, repository, configcompanytypesrepository, configcustomertypesrepository, configgroupproductrepository, configgroupwarrantyrepository, configorderstatusrepository, configordertypefilterrepository, configordertyperepository, configordertypewarrantyrepository, configproductgrouprepository, configproducttyperepository, configreclaimrepository, configstorerepository, configwarrantyrepository) {

    var refs = {};

    /**
    * AdminUnitOfWork ctor
    * @constructor
    */
    var ConfigUnitOfWork = (function () {

        var configUnitOfWork = function () {
            var provider = configmanagerprovider.create();

            /**
            * Has the current AdminUnitOfWork changed?
            * @method
            * @return {bool}
            */
            this.hasChanges = function () {
                return provider.manager().hasChanges();
            };

            /**
            * Commit changeset
            * @method
            * @return {promise}
            */
            this.commit = function () {
                var saveOptions = new breeze.SaveOptions({ resourceName: routeconfig.saveAdminChangesUrl });

                return provider.manager().saveChanges(null, saveOptions)
                    .then(function (saveResult) {
                        app.trigger('saved', saveResult.entities);
                    });
            };

            /**
            * Rollback changes
            * @method
            */
            this.rollback = function () {
                provider.manager().rejectChanges();
            };

            this.configcompanytypesrepository = configcompanytypesrepository.create(provider, "Company_Type", routeconfig.configCompanyTypes);
            this.configcustomertypesrepository = configcustomertypesrepository.create(provider, "Customer_Type", routeconfig.configCustomerTypes);
            this.configgroupproductrepository = configgroupproductrepository.create(provider, "GroupProduct", routeconfig.configGroupProducts);
            this.configgroupwarrantyrepository = configgroupwarrantyrepository.create(provider, "GroupWarranty", routeconfig.configGroupWarranties);
            this.configorderstatusrepository = configorderstatusrepository.create(provider, "Order_Status", routeconfig.configOrderStatuses);
            this.configordertypefilterrepository = configordertypefilterrepository.create(provider, "OrderTypeFilter", routeconfig.configOrderTypeFilters);
            this.configordertyperepository = configordertyperepository.create(provider, "Order_Type", routeconfig.configOrderTypes);
            this.configordertypewarrantyrepository = configordertypewarrantyrepository.create(provider, "OrderTypeWarranty", routeconfig.configOrderTypeWarranties);
            this.configproductgrouprepository = configproductgrouprepository.create(provider, "Product_Group", routeconfig.configProductGroups);
            this.configproducttyperepository = configproducttyperepository.create(provider, "Product_Type", routeconfig.configProductTypes);
            this.configreclaimrepository = configreclaimrepository.create(provider, "Reclaim", routeconfig.configReclaims);
            this.configstorerepository = configstorerepository.create(provider, "Store", routeconfig.configStores);
            this.configwarrantyrepository = configwarrantyrepository.create(provider, "Warranty", routeconfig.configWarranties);
        };

        return configUnitOfWork;
    })();

    var SmartReference = (function () {

        var ctor = function () {
            var value = null;

            this.referenceCount = 0;

            this.value = function () {
                if (value === null) {
                    value = new ConfigUnitOfWork();
                }

                this.referenceCount++;
                return value;
            };

            this.clear = function () {
                value = null;
                this.referenceCount = 0;

                clean();
            };
        };

        ctor.prototype.release = function () {
            this.referenceCount--;
            if (this.referenceCount === 0) {
                this.clear();
            }
        };

        return ctor;
    })();

    return {
        create: create,
        get: get
    };

    /**
     * Get a new AdminUnitOfWork instance
     * @method
     * @return {AdminUnitOfWork}
    */
    function create() {
        return new ConfigUnitOfWork();
    }

    /**
     * Get a new AdminUnitOfWork based on the provided key
     * @method
     * @param {int/string} key - Key used in the reference store
     * @return {promise}
    */
    function get(key) {
        if (!refs[key]) {
            refs[key] = new SmartReference();
        }

        return refs[key];
    }

    /**
     * Delete references
     * @method         
    */
    function clean() {
        for (key in refs) {
            if (refs[key].referenceCount == 0) {
                delete refs[key];
            }
        }
    }
});

我解决了,虽然我认为这违反了 KO 和 Breezes 的原则。

解决方案是触发 setModified();

我添加了这个所以我的编辑方法。

if (diagResult === 'update') {
      //update
      company_type.entityAspect.setModified();
      Save();
}

这强制 .hasChanged 为 return true,并启动了保存。

还有其他方法吗?