two-way binding between object attribute array (enum on server) and ember checkbox group

前端 未结 1 1816
慢半拍i
慢半拍i 2020-12-30 12:35

I am looking for a solution to bind an object attribute that contains an array of string (representing an enum on the server) to a list of checkboxes. The binding should be

1条回答
  •  一整个雨季
    2020-12-30 13:15

    A generic way to handle a two way binding between an Ember object and Checkboxes can be implemented using plain Ember.js without the need of any plugins if you are willing to sync the enums on the server and the client manually (using AJAX or WebSockets). Note that Ember can update the list of options with Checkbox automatically after a sync.

    So henceforth, I will assume that you have am enum with roles as an Ember Array:

    App.Roles = [ "USER", "ADMIN", "GUEST" ];
    

    Then we will show the options available to the user in a CollectionView like this (the template is given below).

    OptionsView = Em.CollectionView.extend({
        contentBinding: 'App.Roles',  // Show a list of _all_ available roles
        userBinding: 'App.User',      // This points to the active user
        tagName: 'ul',                // Shown as a 
      itemViewClass: Em.View.extend({ userBinding: 'parentView.user', // For convenience templateName: 'user-roles' // Defined later }) });

    The template for each option is:

     
    

    Note that the use of tag makes sure that the Checkbox's click event is fired on clicking anywhere on the tag.

    Finally the App.RoleCheckbox is an extension of the Ember.Checkbox class which handles the checked property and click event to toggle the role:

    App.RoleCheckbox = Em.Checkbox.extend({
        userRolesBinding: 'parentView.user.roles', // Points to the roles of the user
    
        checked: function () {
            var userRoles = this.get('userRoles');
            return userRoles.contains(this.get('content'));
        }.property('content', 'userRoles.@each'),
    
        click: function (evt) {
            var isPresent = this.get('checked'),
                userRoles = this.get('userRoles'),
                role      = this.get('content');
    
             if (!isPresent) { 
                 userRoles.pushObject(role); 
             } else {
                 userRoles.removeObject(role);
             }
         }
    });
    

    An working example of this is: http://jsfiddle.net/BLQBf/ (Look at the console to see the log messages)

    Note that this is not completely Ember-esque, since the View is doing part of the job meant for the controller. Ideally, the click event would call a function on the RoleCheckboxController which would make changes to the User object.

    0 讨论(0)
提交回复
热议问题