Angular grid not saving new records

3 posts, 0 answers
  1. Joel
    Joel avatar
    16 posts
    Member since:
    Feb 2015

    Posted 28 Mar Link to this post

    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. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 01 Apr Link to this post

    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!
     
  3. UI for ASP.NET AJAX banner
  4. Joel
    Joel avatar
    16 posts
    Member since:
    Feb 2015

    Posted 04 Apr in reply to Daniel Link to this post

    Specifying the sync function worked for me.  Thanks!

    Joel

Back to Top