使用BreezeJS在Durandal中显示模态

时间:2013-04-02 15:20:58

标签: javascript knockout.js modal-dialog breeze durandal

我很长时间都在努力解决这个问题,并想到为什么不在Stackoverflow上问这个问题! 我的问题如下:

我正在使用Durandal和BreezeJS创建单页面应用程序(SPA)。每当用户创建一些新东西时,就会调用Breeze Lib中的createEntity函数,并返回我的对象​​。我将它推入Ko.observablearray并且瞧它工作得很好;)

直到这一切都运转良好。

但现在是棘手的部分,我使用ko.observablearray创建一个带有data-bind的表。每行都是可点击的,当您单击一行时,将调用SelectedMemo函数并成功传递“item”。但是在这里,当这个函数需要创建自定义模态时,没有任何反应。我收到错误/app/views/.html不存在。我知道这里发生了什么,它试图路由到一个不存在的页面,因为没有创建实体的View和model-view。

如何解决此问题?那么当我点击表格中的一行时,会看到我项目的所有数据吗?

这是迄今为止的代码:

VIew-model:

    define(function (require) {
    var router = require('durandal/plugins/router'),
        app = require('durandal/app'),
        system = require('durandal/system'),
        addmemo = require('viewmodels/modals/addMemo'),
        memo = require('viewmodels/modals/memo'), //probably in the models folder but for now its okay
        dataservice = require('services/dataservice'),
        memos = ko.observableArray([]),
        suspendItemSave = false;

    function extendMemo(memoToExtend) {
        if (memoToExtend.isEditing) return; // already extended

        memoToExtend.isEditing = ko.observable(false);
        //Deze functie wordt getriggerd zodra het aanpassen klaar is!

        // listen for changes with Breeze PropertyChanged event
        memoToExtend.entityAspect.propertyChanged.subscribe(function () {
            if (memoToExtend.propertyChangedPending || suspendItemSave) { return; }
            // throttle property changed response
            // allow time for other property changes (if any) to come through
            memoToExtend.propertyChangedPending = true;
            setTimeout(validateAndSaveModifiedItem, 10);

            function validateAndSaveModifiedItem() {
                if (memoToExtend.entityAspect.entityState.isModified()) {
                    if (memoToExtend.entityAspect.validateEntity()) {
                        dataservice.saveChanges();
                    } else { // errors
                        // handleItemErrors(memoToExtend);
                        memoToExtend.isEditing(true); // go back to editing
                    }
                }
                memoToExtend.propertyChangedPending = false;
            }
        });
    }

    function init() {
        dataservice = new dataservice('api/memo');
        dataservice.getAllRows('AllMemos').then(function (data) {
            data.results.forEach(function (item) {
                //Important step otherwise you are not able to create a memo modal!
                extendMemo(item);
                // memos.push(new memo(item));
                memos.push(item);
            });
            system.log("Initialization succesfull!");
        }).fail(function() {
            system.log("Error initialization!");
        });
    }

    init();
    return {
        displayName: 'Estimating page',
        memos: memos,
        activate: function() {
            system.log("Estimating page started!");
        },
        canDeactivate: function() {
            return app.showMessage('Are you sure you want to leave this page and stop estimating?', 'Navigate', ['Yes', 'No']);
        },
        addMemo: function() {
            app.showModal(new addmemo()).then(function (result) {
                //maby first extend? For editing on the go see hot towel
                if (result != undefined) {                
                    var memoN = dataservice.createT({
                        Description: result[0].Description,
                        CreationDate: result[0].CreationDate,
                        Employee: result[0].User,
                        Type: result[0].Type
                    }, 'tblMemo');

                    if (memoN.entityAspect.validateEntity()) {
                        extendMemo(memoN); //deze 
                        //memos.push(new memo(memoN)); //& deze moeten gewrapped worden!!! anders werkt de entityAspect niet
                        memos.push(memoN);
                        dataservice.saveChanges();
                    }

                    /*
                    if (memoN.entityAspect.validateEntity()) {
                        //memos.push(memoN); //this is not the right thing to add this should be a memo Object!
                        extendMemo(memoN);     
                       // extendMemo(newMemo);
                        memos.push(new memo(memoN.Employee(), memoN.Description(), memoN.Type(), memoN.CreationDate()));
                        dataservice.saveChanges();
                    }*/
                }
            }).fail(function(result) {
                //in future show nice error message, hmmm toastr....?
            });
        },
        selectedMemo: function (selectedMemo, element) {
            //need to make a temp object with data before user clicks okay button or what so ever.
            //THis because the input fields are all observables
            if (selectedMemo) {
                selectedMemo.isEditing(true);
            }

            app.showModal(selectedMemo).then(function (result) {
                if (result) {
                    if (selectedMemo) {
                        selectedMemo.isEditing(false);
                        memos.remove(selectedMemo);
                        selectedMemo.entityAspect.setDeleted();
                        dataservice.saveChanges();
                    }
                }
            }).fail(function() {

            });


            //futher use for deleting memo
            /*
            app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (result) {
                if (result == "Yes") {
                    memos.remove(selectedMemo);
                    selectedMemo.entityAspect.setDeleted();
                    dataservice.saveChanges();
                }
            });
            */ 
        }
    };
});

此外,我尝试创建一个Memo对象,但是当我这样做时,EntityAspect在我的项目中丢失了!但那么模态是有效的吗?怎么解决这个问题?

更新2:

我重写了我的备忘录模型,因此它将实体保存在变量中。但是不再触发PropertyPendingChanged:S

1 个答案:

答案 0 :(得分:5)

所以我终于做到了:)我已经对此进行了3天的编码,但我确实有效了!

这是我对我的代码所做的,我创建了Memo.js,它只包含实体的变量。在我看来,我称这个变量和他的数据。当用户编辑值时,将自动触发订阅功能,并在数据库中传递新值。希望它有用,每个XD花了我整整3天约8小时

浏览

memo.html

<div class="messageBox">
    <div class="modal-header">
        <h2>Memo details</h2>
    </div>
    <div class="modal-body">
        Employee: <input type="text" data-bind="value: MemoEntity._latestValue.Employee"/>
        Description: <input type="text" data-bind="value: MemoEntity._latestValue.Description"/>
        Type: <input type="text" data-bind="value: MemoEntity._latestValue.Type"/>
    </div>
    <div class="modal-footer">
        <ul class="btn-group">
            <button class="btn" data-bind="click: closeModal">Ok</button>
            <button class="btn btn-primary" data-bind="click: deleteMemo">Delete</button>
        </ul> 
    </div>
</div>

备忘录模型 - 视图

(function () {
    var _this = this;
    //self.dataservice = require('services/dataservice');
    define(function (require) {
        var Memo;
        return Memo = (function () {
            function Memo(dataForMemo) {
                this.MemoEntity = ko.observable(dataForMemo);

               // this.Employee = ko.observable(dataForMemo.entityAspect.entity.Employee());
               // this.Description = ko.observable(dataForMemo.entityAspect.entity.Description());
               // this.Type = ko.observable(dataForMemo.entityAspect.entity.Type());
               // this.CreationDate = ko.observable(dataForMemo.entityAspect.entity.CreationDate());
               // this.isEditing = dataForMemo.entityAspect.entity.isEditing;
            }

            Memo.prototype.closeModal = function () {
                return this.modal.close(false);
            };

            Memo.prototype.deleteMemo = function () {
                return this.modal.close(true);
            };
            return Memo;
        })();
    });
}).call(this);

我的页面js

模型 - 视图

define(function (require) {
    var router = require('durandal/plugins/router'),
        app = require('durandal/app'),
        system = require('durandal/system'),
        addmemo = require('viewmodels/modals/addMemo'),
        memo = require('viewmodels/modals/memo'), //probably in the models folder but for now its okay
        dataservice = require('services/dataservice'),
        memos = ko.observableArray([]),
        suspendItemSave = false;

    function extendMemo(memoToExtend) {
        if (memoToExtend.isEditing) return; // already extended

        memoToExtend.isEditing = ko.observable(false);
        //Deze functie wordt getriggerd zodra het aanpassen klaar is!

        // listen for changes with Breeze PropertyChanged event
        memoToExtend.entityAspect.propertyChanged.subscribe(function () {
            if (memoToExtend.propertyChangedPending || suspendItemSave) { return; }
            // throttle property changed response
            // allow time for other property changes (if any) to come through
            memoToExtend.propertyChangedPending = true;
            setTimeout(validateAndSaveModifiedItem, 10);

            function validateAndSaveModifiedItem() {
                if (memoToExtend.entityAspect.entityState.isModified()) {
                    if (memoToExtend.entityAspect.validateEntity()) {
                        dataservice.saveChanges();
                    } else { // errors
                        // handleItemErrors(memoToExtend);
                        memoToExtend.isEditing(true); // go back to editing
                    }
                }
                memoToExtend.propertyChangedPending = false;
            }
        });
    }

    function init() {
        dataservice = new dataservice('api/memo');
        dataservice.getAllRows('AllMemos').then(function (data) {
            data.results.forEach(function (item) {
                //Important step otherwise you are not able to create a memo modal!
                extendMemo(item);
                var t = new memo(item);
                memos.push(t);
                //memos.push(item);
            });
            system.log("Initialization succesfull!");
        }).fail(function() {
            system.log("Error initialization!");
        });
    }

    init();
    return {
        displayName: 'Estimating page',
        memos: memos,
        activate: function() {
            system.log("Estimating page started!");
        },
        canDeactivate: function() {
            return app.showMessage('Are you sure you want to leave this page and stop estimating?', 'Navigate', ['Yes', 'No']);
        },
        addMemo: function() {
            app.showModal(new addmemo()).then(function (result) {
                //maby first extend? For editing on the go see hot towel
                if (result != undefined) {                
                    var memoN = dataservice.createT({
                        Description: result[0].Description,
                        CreationDate: result[0].CreationDate,
                        Employee: result[0].User,
                        Type: result[0].Type
                    }, 'tblMemo');

                    if (memoN.entityAspect.validateEntity()) {
                        extendMemo(memoN); //deze 
                        memos.push(new memo(memoN)); //& deze moeten gewrapped worden!!! anders werkt de entityAspect niet
                        dataservice.saveChanges();
                    }

                    /*
                    if (memoN.entityAspect.validateEntity()) {
                        //memos.push(memoN); //this is not the right thing to add this should be a memo Object!
                        extendMemo(memoN);     
                       // extendMemo(newMemo);
                        memos.push(new memo(memoN.Employee(), memoN.Description(), memoN.Type(), memoN.CreationDate()));
                        dataservice.saveChanges();
                    }*/
                }
            }).fail(function(result) {
                //in future show nice error message, hmmm toastr....?
            });
        },
        selectedMemo: function (selectedMemo, element) {
            //need to make a temp object with data before user clicks okay button or what so ever.
            //THis because the input fields are all observables
        //    if (selectedMemo) {
                //selectedMemo.MemoEntity._latestValue.entity.isEditing(true);
               // selectedMemo.isEditing(true);
        //    }

            app.showModal(selectedMemo).then(function (result) {
                if (result) {


                    app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (resultMes) {
                        if (resultMes == "Yes") {
                            memos.remove(selectedMemo);
                            selectedMemo.MemoEntity._latestValue.entityAspect.setDeleted();
                            dataservice.saveChanges();
                        }
                    });


                }
            }).fail(function() {

            });


            //futher use for deleting memo
            /*
            app.showMessage('Do you want to delete this memo?', 'Delete memo', ['Yes', 'No']).then(function (result) {
                if (result == "Yes") {
                    memos.remove(selectedMemo);
                    selectedMemo.entityAspect.setDeleted();
                    dataservice.saveChanges();
                }
            });
            */

        }
    };
});

我对备忘录的看法

<table class="table table-hover table-striped">
                    <thead>
                        <tr>
                            <th>Created</th><th>User</th><th>Memo</th><th>Type</th>
                        </tr>
                    </thead>
                    <tbody data-bind="visible: memos().length > 0, foreach: memos">
                        <tr data-bind="click: $parent.selectedMemo">
                            <td data-bind="text: MemoEntity._latestValue.CreationDate"></td>
                            <td data-bind="text: MemoEntity._latestValue.Employee"></td>
                            <td data-bind="text: MemoEntity._latestValue.Description"></td>
                            <td data-bind="text: MemoEntity._latestValue.Type"></td>
                        </tr>
                    </tbody>
                    <tbody data-bind="visible: memos().length == 0">
                        <tr>
                            <td colspan="4">NO MEMOS ADDED YET</td>
                        </tr>
                    </tbody>
                </table> 

希望它有所帮助;)