This is a migrated thread and some comments may be shown as answers.

Angular grid not saving new records

2 Answers 126 Views
Integration with other JS libraries
This is a migrated thread and some comments may be shown as answers.
Joel
Top achievements
Rank 1
Iron
Joel asked on 28 Mar 2016, 10:15 PM

I have a many-to-many relationship between Contacts and Users in a UserContact entity.  A contact and its related users are pulled down in a single JSON request.  The contact object has a userContacts property that contains all of the related userContact records.  Each userContact has as user property that contains additional info about the user.  I am using a grid to maintain the users associated with the current contact (contact.userContacts).  I put the grid in an Angular 1.5 component, and I pass in the current contact. 

Everything is working, except that new records added in the grid are not making it back to the model.  If I change the user on an existing record, it works fine.  I tried the suggestions on this page, but I couldn't get it to work.  I'm not sure how to apply the ObservableArray() to my code.  I am using a drop-down list in the grid, but that appears to be working fine.  Can you see what I'm doing wrong?

Here's the HTML pulling in the component to my main Contact view:

<div class="col-sm-offset-1 col-md-offset-1">
    <contact-user-list contact="vm.contact" />
</div>

Here's the Angular HTML template for the component:

<div kendo-grid id="contractUserGrid"
     k-options="contactUserList.userGridOptions()"
     k-rebind="contactUserList.contact"
     k-selectable="true"
     k-navigatable="true">
</div>

Javascript for the component:

(function () {
    'use strict';
 
    var app = angular.module("app.contacts");
 
    app.component('contactUserList', {
        templateUrl: 'app/contacts/contact-user-list.html',
        controllerAs: 'contactUserList',
        controller: ['userService', ContactUserListController],
        bindings: {
            contact: '='
        }
    });
 
    function ContactUserListController(userService) {
 
        var vm = this;
 
        vm.userList = userService.getUserList();
        vm.userDropDown = function (container, options) {
            var editor = $('<input kendo-drop-down-list required k-data-text-field="\'userName\'" k-data-value-field="\'userID\'" k-data-source="contactUserList.userList" data-bind="value:' + options.field + '"/>')
            .appendTo(container);
        };
 
        vm.userGridOptions = function () {
            return {
                dataSource: vm.userContactsData(),
                toolbar: ["create"],
                editable: true,
                columns: [
                    { field: "user", title: "Counselor3", editor: vm.userDropDown, template: "#=user.userName#" },
                    { command: "destroy", title: " ", width: "90px" }
                ]
            };
        };
 
        vm.userContactsData = function () {
            var dataSource = new kendo.data.DataSource({
                data: vm.contact ? vm.contact.userContacts : null,
                autoSync: true,
                schema: {
                    model: {
                        id: "userContactID",
                        fields: {
                            userContactID: { defaultValue: 0 },
                            userID: { defaultValue: 0 },
                            contactID: { defaultValue: vm.contact ? vm.contact.contactID : 0 },
                            user: { defaultValue: { userID: 1, userName: "Administrator", userRole: "admin" } }
                        }
                    }
                }
            });
            return dataSource;
        };
 
    }
 
})();

Finally, userService.getUserList():

function getUserList() {
    if (!svc.userData) {
        svc.userData = new kendo.data.DataSource({
            type: "webapi",
            transport: {
                read: "../api/users/",
                cache: "inmemory"
            },
            schema: {
                data: "data",
                total: "total",
                errors: "errors"
            }
        });
    }
 
    return svc.userData;
}

2 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 01 Apr 2016, 06:58 AM
Hello Joel,

The dataSource works with a copy of the original array so only changes made to the objects will be reflected. In most cases you can use ObservableArray or DataSource instance in order for the changes to be automatically reflected but because you are using k-rebind, this will cause the grid to be recreated on each change. Therefore I can suggest either to update the original array on sync:
var dataSource = new kendo.data.DataSource({
    data: vm.contact.userContacts,
    sync: function (e) {
        setTimeout(function () {
            vm.contact.userContacts = dataSource.data().toJSON();
        }, 0);
    },
    ...
or to use custom functions for the transport operations in order to sync the changes back to the original array e.g.
vm.userContactsData = function () {
    var dataSource = new kendo.data.DataSource({
        transport: {
            read: function (options) {
                options.success(vm.contact.userContacts);
            },
            create: function (options) {
                options.data.userContactID = kendo.guid();
                vm.contact.userContacts.push(options.data);
                options.success(options.data);
            },
            update: function (options) {
                options.success();
            },
            destroy: function (options) {
                var userContacts = vm.contact.userContacts;
                for (var i = 0; i < userContacts.length; i++) {
                    if (userContacts[i].userContactID == options.data.userContactID) {
                        userContacts.splice(i, 1);
                        break;
                    }
                }
                options.success();
            }
        },
        ...


Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Joel
Top achievements
Rank 1
Iron
answered on 04 Apr 2016, 09:48 PM

Specifying the sync function worked for me.  Thanks!

Joel

Tags
Integration with other JS libraries
Asked by
Joel
Top achievements
Rank 1
Iron
Answers by
Daniel
Telerik team
Joel
Top achievements
Rank 1
Iron
Share this question
or