Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ember.js 如何管理余烬中的多个复选框?_Ember.js_Handlebars.js - Fatal编程技术网

Ember.js 如何管理余烬中的多个复选框?

Ember.js 如何管理余烬中的多个复选框?,ember.js,handlebars.js,Ember.js,Handlebars.js,我仍在试图弄清楚余烬是如何工作的,我想了解更多有关在余烬中管理多个复选框的信息。 以下是我试图做的: 正如您所看到的,所有复选框都被选中,而选中的函数不会被调用 正确的方法是什么?现在检查一下 您必须添加genre.isChecked,否则相同的isChecked将绑定到所有复选框 顺便说一句,如果您想为每个项目添加控制器,可以在数组控制器中添加ItemController。这里是另一个例子 /* controllers */ App.AnimesController = Ember.Array

我仍在试图弄清楚余烬是如何工作的,我想了解更多有关在余烬中管理多个复选框的信息。
以下是我试图做的:
正如您所看到的,所有复选框都被选中,而选中的函数不会被调用
正确的方法是什么?

现在检查一下

您必须添加genre.isChecked,否则相同的isChecked将绑定到所有复选框

顺便说一句,如果您想为每个项目添加控制器,可以在数组控制器中添加ItemController。这里是另一个例子

/* controllers */
App.AnimesController = Ember.ArrayController.extend({
  itemController: 'anime'
});

你得照杰克说的做

完成后,您可以使用绑定“知道”要检查哪一个。也就是说,您不需要自己知道,您只需要将正确的值绑定到正确的位置

无论如何,这个jsbin应该可以缓解您的问题。。。请注意,控制台使用该值进行设置,并在正确的分层/位置触发


好的,关于你的其他问题,我已经基本完成了你的应用程序:


谢谢你的回答,但我仍然不知道如何知道选中了哪一个,以便它可以用于过滤,例如,但最后你返回
this.get('model.isChecked')
。。它是
未定义的
。。为什么?而且现在您正在为复选框使用另一个控制器。。我如何在App.AnimesController中观察它们。它不是复选框的控制器,而是各类型的控制器-作为每种类型的itemController。您需要这样做的原因是,您没有关于实际类型本身的属性(这可能是正确的)。这完全取决于你想做什么。您似乎希望根据这些内容的选中或未选中状态进行筛选。我建议您使用我给您的isChecked函数来驱动过滤器代码的更改。。。(即使用它来管理包装过滤项的控制器上的某些状态)。我正在回答您的具体问题。。。但是如果你真正问的是如何创建一个复选框列表来驱动一组过滤过的对象,那么这是一个不同的问题!如果你想问的话,请随便问另一个问题,但我想我已经回答了你的第一个问题。您可能想问的问题实际上是如何使用复选框来管理ember中的数据支持关联。我会用一种与你所做的完全不同的方式来讨论这个问题,所以这是一个更高层次架构的问题。好吧,现在我明白你的实际要求和试图做什么了,我会仔细考虑一下,看看我能做些什么。对不起:/我不是故意让你写我的应用。。但我真的觉得余烬令人困惑。。所以非常感谢!这真是帮了大忙哈哈,我不是故意说脏话的!:)是的,这让人困惑。别担心。我觉得这也很困惑和困难。我实际上正在制作一个视频系列,应该从绝对初学者。。。所以这可能会有帮助。也许我应该为此推出kickstarter:)你明白我所做的一切吗?确保你理解其中的逻辑是很好的。我试着添加注释以提供帮助,但可能仍然有点混乱。是的,代码非常清楚。。但是我不明白
需要:[“动画”]
的含义。。我没有意识到使用
this.get('controllers.animes.selectedGenreIds')
访问另一个控制器的可能性,例如:)并确保在完成系列时通知我^^^^实际需要['something']是您如何指定可以使用它访问的内容。get('controllers.something');(如果有道理的话)。所以您可以说needs:['animes'],它将控制器“挂载”到controllers属性中,然后您可以使用此.get('controllers.animes')访问该属性;
/* controllers */
App.AnimesController = Ember.ArrayController.extend({
  itemController: 'anime'
});
App = Ember.Application.create();
App.ApplicationAdapter = DS.RESTAdapter.extend({
    host: '/api',
    namespace: 'fr'
});

/* router */
App.Router.map(function() {
  this.resource('animes');
});
App.AnimesRoute = Ember.Route.extend({
    model: function() {
        return this.store.find('anime');
    },
  setupController: function(controller, model) {
        this._super(controller, model);
        this.store.find('genre').then(function(genres){
            controller.set('genres', genres);
        });
    }
});

/* models */
var model = DS.Model,
    attr = DS.attr,
    hasMany = DS.hasMany;

App.Genre = model.extend({
    animes: hasMany('anime', {async: true}),
    nom: attr('string')
});
App.Anime = model.extend({
    nom: attr('string'),
    parution: attr('number'),
    synopsis: attr('string'),
    likes: attr('number'),
    auteur: attr('string'),

    genres: hasMany('genre', {async: true})
});
/* controllers */
App.GenreController = Em.ObjectController.extend({
  isChecked: function(key, value) {
    if(arguments.length > 1) {
      // setter
      console.log('huzzah' + this.get('id') + ' val: ' + value);      
    }
    // always return the value for the getter and the setter
    return this.get('model.isChecked');
  }.property(),
  actions: {
  click: function() {
    console.log("hi");
  }    
  }
});

/* mockjax */
var animes = [
    {
        id: 1,
        nom: 'Blah',
        parution: 2014,
        genres: [1, 3],
        synopsis: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore, eveniet, ab pariatur omnis dolor sunt alias atque voluptate neque reiciendis maiores impedit quibusdam perferendis optio ratione expedita adipisci et. Cupiditate!',
        likes: 206,
        auteur: 'Moi :p'
    }
],
genres = [
    {
        id: 1,
        nom: 'action',
        animes: []
    },
    {
        id: 2,
        nom: 'magie',
        animes: [1]
    },
    {
        id: 3,
        nom: 'amour et amitier',
        animes: []
    },
    {
        id: 4,
        nom: 'aventures',
        animes: [1]
    }
];
$.mockjax({
  url: '/api/fr/animes',
  responseTime: 750,
  responseText: {
    'animes': animes
  }
});
$.mockjax({
  url: '/api/fr/genres',
  responseTime: 750,
  responseText: {
    'genres': genres
  }
});
App = Ember.Application.create();
App.ApplicationAdapter = DS.RESTAdapter.extend({
    host: '/api',
    namespace: 'fr'
});

/* router */
App.Router.map(function() {
  this.resource('animes');
});
App.AnimesRoute = Ember.Route.extend({
  model: function() {
    return this.store.find('anime');
  },
  setupController: function(controller, model) {
    this._super();
    this.store.find('genre').then(function(genres) {
      controller.set('genres', genres);
    });
    controller.set('model', model);
  }
});

/* models */
var model = DS.Model,
    attr = DS.attr,
    hasMany = DS.hasMany;

App.Genre = model.extend({
    animes: hasMany('anime', {async: true}),
    nom: attr('string')
});
App.Anime = model.extend({
    nom: attr('string'),
    parution: attr('number'),
    synopsis: attr('string'),
    likes: attr('number'),
    auteur: attr('string'),

    genres: hasMany('genre', {async: true})
});
/* controllers */
App.AnimesController = Em.ArrayController.extend({
  genres: Em.A([]),
  selectedGenreIds: Em.A([]), // a set of ids
  selectedGenres: function() {
    var genres = this.get('genres'),
        selectedGenreIds = this.get('selectedGenreIds');
    return genres.filter(function(genre) {
      return selectedGenreIds.contains(genre.get('id'));
    });
  }.property('selectedGenreIds.@each', 'genres.@each'),
  selectedAnimes: function() {
    var allAnimes = this.get('model'),
        selectedGenres = this.get('selectedGenres'),
        filteredAnimes;
    // for an anime to be shown, it has to have at
    // least one of its genres selected
    filteredAnimes = allAnimes.filter(function(anime) {
      return anime.get('genres').any(function(animeGenre) {
        return selectedGenres.contains(animeGenre);
      });
    });
    return filteredAnimes;
  }.property('model.@each', 'selectedGenres.@each', 'genres.@each')
});
App.GenreController = Em.ObjectController.extend({
  needs: ['animes'],
  isChecked: function(key, value) {
    if(arguments.length > 1) {
      // setter
      var selectedGenreIds = this.get('controllers.animes.selectedGenreIds'),
          thisId = this.get('id');
      if(!selectedGenreIds.contains(thisId) && value) {
        selectedGenreIds.addObject(thisId);
      } else {
        selectedGenreIds.removeObject(thisId);
      }
    }
    // always return the value for the getter and the setter
      return value;
  }.property('controllers.animes.selectedGenreIds')
});

/* mockjax */
var animes = [
    {
        id: 1,
        nom: 'Blah',
        parution: 2014,
        genres: [1, 3],
        synopsis: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore, eveniet, ab pariatur omnis dolor sunt alias atque voluptate neque reiciendis maiores impedit quibusdam perferendis optio ratione expedita adipisci et. Cupiditate!',
        likes: 206,
        auteur: 'Moi :p'
    }
],
genres = [
    {
        id: 1,
        nom: 'action',
        animes: []
    },
    {
        id: 2,
        nom: 'magie',
        animes: [1]
    },
    {
        id: 3,
        nom: 'amour et amitier',
        animes: []
    },
    {
        id: 4,
        nom: 'aventures',
        animes: [1]
    }
];
$.mockjax({
  url: '/api/fr/animes',
  responseTime: 750,
  responseText: {
    'animes': animes
  }
});
$.mockjax({
  url: '/api/fr/genres',
  responseTime: 750,
  responseText: {
    'genres': genres
  }
});