0

John Papa の Jumpstart で提供されているガイダンスに従って SPA を構築しています。モデルを作成すると、

modelObservable().entityAspect.entityState.isAdded() = true;

テキスト、ドロップダウン、および modelObservable().entityAspect.entityState.isAdded() = false; を更新します。

私のデータコンテキストで:

  var createProject = function (position) {
            return manager.createEntity(entityNames.project,
                {
                    positionId : position.id(),
                    start : position.start(),
                    memberId : position.memberId()
                });
        };

私のadd viewModelから呼び出されます:

   define(['services/datacontext', 'durandal/plugins/router', 'durandal/system', 'durandal/app', 'services/logger', 'services/uiService'],
    function (datacontext, router, system, app, logger, ui) {
        var model = ko.observable();
        var position = ko.observable();
        var hourTypes = ko.observableArray([]);
        var isSaving = ko.observable(false);
        // init
        var activate = function (routeData) {
            logger.log('Add View Activated', null, 'add', true);
            var positionId = parseInt(routeData.id);

            initLookups();
            return datacontext.getPositionById(positionId, position).then(**createProject**);
        };

        var initLookups = function () {
            logger.log('initLookups', null, 'add', true);
            hourTypes(datacontext.lookups.hourTypes);
        };

        // state

        **var createProject = function () {
            return model(datacontext.createProject(position()));
        }**

        var addNewProject = function () {
            if (position == undefined || position().id() < 1) {
                console.log('callback addNewProject');
                setTimeout(function () {
                    addNewProject();
                }, 1000);
            } else {
                datacontext.addProject(position(), model);
                console.log(model().id());
                return;
            }
        }

        var **save** = function () {
            isSaving(true);
            **datacontext.saveChanges()**
                    .then(goToEditView).fin(complete);

            function complete() {
                isSaving(false);
            }
            function goToEditView() {
                isSaving(false);
                var url = '#/Projects/';
                router.navigateTo(url + model().id());
            }
        };

        var vm = {
            activate: activate,
            hourTypes: hourTypes,
            isAdded: isAdded,
            model: model,
            save: save,
            title: 'Details View'
        };

        return vm;

});

html

<section  data-bind="with:model">
     <h1 data-bind="text: name"> <i class="icon-asterisk" data-bind="visible: hasChanges" style="font-size: 30px;"></i></h1>
        <div class="errorPanel"></div>
        <div id="overview" class="project" >
            <div class="row">
                <div class="span4">
                    <label class="requiredLabel">Name*</label>
                    <input type="text" name="name" data-bind="value: name" style="width: 27em;" class="required" placeholder="Project Name" required validationMessage="Project Name required" /><span class="k-invalid-msg" data-for="title"></span>
                </div>
            </div>
            <div class="row">
                <div class="span3"><label class="requiredLabel">Start*</label></div>
                <div class="span3"><label class="requiredLabel">End</label></div>
            </div>
            <div class="row">
                <div class="span3"><input name="start" data-bind="shortDate: start" class="date required" required="required" placeholder="mm/dd/yyyy" style=" width:142px"></div>
                <div class="span3"><input name="end"   data-bind="shortDate: end"  class="date" placeholder="mm/dd/yyyy"  style=" width:142px"><span class="k-invalid-msg" data-for="end"></span></div>
            </div>
            <br/>
            <div class="row">
                <div class="span3"><label for="hourType" class="requiredLabel">Measure As*</label></div>
                <div class="span2"><label for="hoursPerWeek" class="requiredLabel">Hours/Week</label></div>
                <div class="span2"><label for="totalHours" class="requiredLabel">Total Hours</label></div>
            </div>   
            <div class="row">
                <div class="span3">
                    <select id="hourType" data-bind="options: $parent.hourTypes, optionsText: 'name', value: hourType" required validationMessage="Measure As required"></select><span class="k-invalid-msg" data-for="hourType"></span>
                </div>
                <div class="span2">
                    <input name="hoursPerWeek" type="number" min="1" max="120" required="required" data-bind="value: hoursPerWeek,  validationOptions: { errorElementClass: 'input-validation-error' }, enable: hourType().id() == 1" class="hours required"" style="width: 80px;"  validationMessage="Hours required"><span class="k-invalid-msg" data-for="projectHours"></span>
                    <span class="k-invalid-msg" data-for="totalHours"></span>
                </div>
                <div class="span2">
                    <input name="totalHours" type="number"  min="40" max="2080" required="required" data-bind="value: totalHours,  validationOptions: { errorElementClass: 'input-validation-error' }, enable: hourType().id() == 2" class="hours required"" style="width: 80px;"  validationMessage="Hours required"><span class="k-invalid-msg" data-for="projectHours"></span>
                    <span class="k-invalid-msg" data-for="totalHours"></span>
                </div>
            </div>
            <div class="row">
                <div class="span4">
                    <label class="requiredLabel">Description*</label><span class="k-invalid-msg" data-for="description"></span><span id="posMinDesc" style="visibility:hidden"></span>
                    <textarea id="description" name="description" style="height: 200px; width: 650px;" data-bind="value: description, enabled:true, click: $parent.clearDefaults" rows="4" cols="60" class="richTextEditor k-textbox" required validationMessage="Description required" ></textarea>
                </div>
            </div>    
        </div>
    <div class="button-bar">
        <button class="btn btn-info"  data-bind="click:  $parent.goBack"><i class="icon-hand-left"></i> Back</button>
        <button class="btn btn-info"  data-bind="click:  $parent.save, enable:  $parent.canSave"><i class="icon-save"></i> Save</button>
    </div>
</section>

私のコントローラーに送られるjsonのそよ風はこれです:

{ "entities": [ { "Id": -1, "Description": "poi", "End": null, "Gauge": 0, "Score": 0, "HourTypeId": 1, "HoursPerWeek": 45, "HourlyRate": null, "TotalHours": null, "WeightedHours": 0, "CreditMinutes": 0, "TotalCompensation": null, "IsCurrent": false, "Name": "poi", "PositionId": 1, "MemberId": 1, "Start": "2011-09-01T00:00:00Z", "undefined": false, "entityAspect": { "entityTypeName": "Project:#SkillTraxx.Model", "defaultResourceName": "Projects", "entityState": "変更済み", "originalValuesMap": { "Name": "", "HourTypeId": 0, "HoursPerWeek": null, "Description": "" }, "autoGeneratedKey": { "propertyName": "Id", "autoGeneratedKeyType" : "ID" } } } ], "saveOptions": {} }

ご覧のとおり、上記は正しくありません。b/c 状態は「変更済み」であり、Id = -1 です。これにより、サーバー側でエラーがスローされます。DbUpdateConcurrencyException をトラップし、JObject をアンワインドして、"Modified" を added に変更できると思いますが、コードの匂いが全体にかかっています。

誰かがこのすべての中で顔と手のひらの瞬間を見つけるのを手伝ってくれるなら、私は準備ができています. ご覧いただきありがとうございます。

4

1 に答える 1

1

Face Palmed IT Jays のアドバイスを受けて、html を削除し始めたところ、それが自分のハンドラーであることがわかりました。shortDate ハンドラーの更新メソッドが原因でした。現在の状態が追加された場合に更新を送信しないように、if ステートメントでラップしました。

ko.bindingHandlers.shortDate = {
    init: function (element, valueAccessor) {
        //attach an event handler to our dom element to handle user input
        element.onchange = function () {
            var value = valueAccessor();//get our observable
            //set our observable to the parsed date from the input
            value(moment(element.value).toDate());
        };
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);
        if (valueUnwrapped) {
            element.value = moment(valueUnwrapped).format('L');
            if (!viewModel.entityAspect.entityState.isAdded())
            {
                **viewModel.entityAspect.setModified();**
            }
        }
    }
};
于 2013-06-18T04:28:46.350 に答える