mercredi 9 décembre 2015

Ember checklist

JsBin: http://ift.tt/1IURgiP

I have a check-list component. I keep track of the checked items in a property players. If a club checked/unchecked, all its player should checked/unchecked.

Reproduce the problem:

  1. check a club (eg. Bayern Munich). All players are correctly checked.
  2. uncheck one player, the club's check box changes to indeterminate. (as it should)
  3. uncheck the 2nd player, the club's check box is correctly unchecked.
  4. now try to check the club again: the players wont checked as it expected
App = Ember.Application.create();

App.Router.map(function() {
  // put your routes here
});

App.ApplicationAdapter = DS.JSONAPIAdapter;

App.Club = DS.Model.extend({
  name: DS.attr('string'),
  players: DS.hasMany('player')
});

App.Player = DS.Model.extend({
  name: DS.attr('string')
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return this.store.findAll('club');
  }
});

App.IndexController = Ember.Controller.extend({
  actions: {

  }
});

App.CheckListComponent = Ember.Component.extend({
  actions: {
    check: function(item) {
      /*
      item.toggleProperty('checked');
      item.get('players').setEach ('checked', item.get('checked'));
      */
    }
  }
});

App.ClubListComponent = Ember.Component.extend({
  init: function() {
    this._super();
    this.set('players', Ember.A([]));
  },
  checked: Ember.computed('players', 'players.length', {
    get(key) {
      console.log(key);
      return (this.get('players.length') === this.get('model.players.length'));
    },
    set(key, value) {
      return value

    }
  }),
  indeterminate: Ember.computed('players.length', function() {
    console.log('indeterminate');
    return (this.get('players.length') !== this.get('model.players.length') && this.get('players.length') > 0);
  }),
  actions: {
    checkPlayer: function(player) {
      console.log('CHECK');
      var id = player.get('id');
      var players = this.get('players');
      if (players.contains(id)) {
        players.removeObject(id);
      } else {
        players.pushObject(id);
      }
      console.log(this.get('players.length'));
    },
    changeAll: function() {
      var state = this.get('checked');
      var res = Ember.A([]);
      console.log(state);
      if (state) {
        this.get('model.players').forEach(function(player) {
          res.pushObject(player.get('id'));
        });

      }
      this.set('players', res);
    }

  }
});

App.ContainsHelper = Ember.Helper.helper(function(params) {
  var needle = params[0];
  var haystack = params[1];
  return haystack.contains(needle);
});

/*---------------Data------------------*/
var clubs = {
  "data": [{
    "attributes": {
      "name": "Benfica"
    },
    "id": "1",
    "relationships": {
      "players": {
        "data": [{
          "id": "3",
          "type": "players"
        }, {
          "id": "2",
          "type": "players"
        }]
      }
    },
    "type": "clubs"
  }, {
    "attributes": {
      "name": "Bayern Munich"
    },
    "id": "2",
    "relationships": {
      "players": {
        "data": [{
          "id": "4",
          "type": "players"
        }, {
          "id": "5",
          "type": "players"
        }]
      }
    },
    "type": "clubs"
  }],
  "included": [{
    "attributes": {
      "name": "Eusebio Silva Ferreira"
    },
    "id": "3",
    "relationships": {
      "club": {
        "data": {
          "id": "1",
          "type": "clubs"
        }
      }
    },
    "type": "players"
  }, {
    "attributes": {
      "name": "João Vieira Pinto"
    },
    "id": "2",
    "relationships": {
      "club": {
        "data": {
          "id": "1",
          "type": "clubs"
        }
      }
    },
    "type": "players"
  }, {
    "attributes": {
      "name": "Franz Beckenbauer"
    },
    "id": "4",
    "relationships": {
      "club": {
        "data": {
          "id": "2",
          "type": "clubs"
        }
      }
    },
    "type": "players"
  }, {
    "attributes": {
      "name": "Thomas Müller"
    },
    "id": "5",
    "relationships": {
      "club": {
        "data": {
          "id": "2",
          "type": "clubs"
        }
      }
    },
    "type": "players"
  }]
};

$.mockjax({
  url: '/clubs',
  dataType: 'json',
  responseText: clubs
});
/* Put your CSS here */

html,
body {
  margin: 20px;
}
.rc-handle:hover {
  border-left: 1px solid;
  border-style: dashed;
  border-top: none;
  border-right: none;
  border-bottom: none;
}
li {
  list-style-type: none;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Ember Starter Kit</title>
  <link rel="stylesheet" href="http://ift.tt/1x2iORp">
  <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">

  <script src="http://ift.tt/1mWWrGH"></script>
  <script src="http://ift.tt/1KmdTjU"></script>
  <script src="http://ift.tt/1H1Z8nl"></script>
  <script src="http://ift.tt/1Y2DLqk"></script>
  <script src="http://ift.tt/1IURero"></script>

  <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
</head>

<body>

  <script type="text/x-handlebars">
    <h2>Table example</h2>
    {{outlet}}
  </script>

  <script type="text/x-handlebars" data-template-name="index">
    {{check-list model=model}} ---------------------------- {{check-list model=model}}
  </script>




  <script type="text/x-handlebars" data-template-name="components/check-list">

    <ul>
      {{#each model as |item|}} {{club-list model=item}} {{/each}}
    </ul>
  </script>
  <script type="text/x-handlebars" data-template-name="components/club-list">
    <li>
      {{input type="checkbox" checked=checked indeterminate=indeterminate change=(action 'changeAll')}} {{model.name}}
      <ul>
        {{#each model.players as |player|}}
        <li>
          {{input type="checkbox" checked=(contains player.id players) change=(action 'checkPlayer' player)}} {{player.name}}
        </li>
        {{/each}}
      </ul>
    </li>
  </script>
</body>

</html>



Aucun commentaire:

Enregistrer un commentaire