Расширенная сортировка Emberjs имеет ассоциацию hasMany как вычисляемое свойство

Я задал вариант этого вопроса здесь. Но в основном мне нужно создать вычисляемое свойство, которое работает с ассоциацией hasMany. Мне нужно выполнить сортировку, аналогичную сортировке javascript sort функция; где я могу сделать что-то вроде

files = ["File 5", "File 1", "File 3", "File 2"];
files.sort(function(a,b){
  return parseInt(b.split(' ').pop()) - parseInt(a.split(' ').pop())
});

результат:

["File 5", "File 3", "File 2", "File 1"]

Вот мой jsbin: http://emberjs.jsbin.com/simayexose/edit?html,js,output

Любая помощь будет принята с благодарностью.

Примечание. Мой jsbin в настоящее время работает неправильно (по причинам, отличным от этого вопроса). Я разместил вопрос об этом здесь. Я просто не хотел затягивать с ответом на этот вопрос.

Обновление 1

Спасибо @engma. Я выполнил инструкцию. На самом деле, я скопировал и вставил то, что было опубликовано. Это новый jsbin. http://emberjs.jsbin.com/roqixemuyi/1/edit?html,js,output

Я все еще ничего не отсортировал, хотя. А даже если бы и было, то все равно не разобрались бы так, как хотелось бы.

Мне нужно что-то вроде следующего: (ниже приведены ошибки, которые я получаю, когда пытаюсь реализовать это в своем коде, а не из jsbin, так как я не могу заставить jsbin работать)

  sortedFiles: function(){
    return this.get('files').sort(function(a,b){
      return parseInt(b.split(' ').pop()) - parseInt(a.split(' ').pop());
    });
  }.property('[email protected]')

Когда я это делаю, я получаю следующую ошибку:

Uncaught TypeError: this.get(...).sort is not a function

Итак, поскольку this.get('files') возвращает обещание, я решил попробовать это;

  sortedFiles: function(){
    return this.get('files').then(function(files){
      return files.sort(function(a,b){
        return parseInt(b.split(' ').pop()) - parseInt(a.split(' ').pop());
      });
    });
  }.property('[email protected]')

Но затем я получаю следующую ошибку:

Uncaught Error: Assertion Failed: The value that #each loops over must be an Array. You passed {_id: 243, _label: undefined, _state: undefined, _result: undefined, _subscribers: }

Кстати, я использую emberjs v1.11.0

И sortBy, который я использую, это ember-cli/node_modules/bower-config/node_modules/mout/array/sortBy.js

Вот код для него

var sort = require('./sort');
var makeIterator = require('../function/makeIterator_');

    /*
     * Sort array by the result of the callback
     */
    function sortBy(arr, callback, context){
        callback = makeIterator(callback, context);

        return sort(arr, function(a, b) {
            a = callback(a);
            b = callback(b);
            return (a < b) ? -1 : ((a > b) ? 1 : 0);
        });
    }

    module.exports = sortBy;

Обновление 2

Итак, чтобы ответить на вопрос, как выполнить расширенную сортировку Emberjs hasMany как вычисляемое свойство; я должен был изменить

  this.get('files').sort(function(a,b){
      ...
  });

  return this.get('files').toArray().sort(function(a,b){
    ...
  });

Это позволило мне использовать сортировку javascript и возвращать нужные отсортированные объекты.


person user2517182    schedule 18.06.2015    source источник


Ответы (1)


Хорошо, во-первых, у вашего JSBin было много проблем, так что давайте рассмотрим их одну за другой.

1- вы не включили сборку Ember-Data, поэтому я включил 1, это нужно для фикстур и моделей

<script src="http://builds.emberjs.com/tags/v1.0.0-beta.15/ember-data.js"></script>

2- Ваши сценарии

var App = window.App = Ember.Application.create({
});
//First this is how to register the adapter
App.ApplicationAdapter = DS.FixtureAdapter.extend({});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    //Second with find you pass in the ID so I am using 1
    //if you want to get all folders use findAll()
    return this.store.find('folder',1);
  } 
});

App.IndexController = Ember.Controller.extend({

});


App.Router.map(function() {
});

App.Folder = DS.Model.extend({
  name: DS.attr('string'),
  files:  DS.hasMany('file',{async:true}),
  sortedFiles: function(){
    //Sorty By has no second parameter, if you need more sorting power, do it your self
    return this.get('files').sortBy('name');
  }.property('[email protected]')

});

App.File = DS.Model.extend({
  name: DS.attr('string'),
  folder: DS.belongsTo('folder',{async:true})
});

App.File.FIXTURES = [
  {
    id: 1,
    name: 'File 5',
    folder:1
  },
  {
    id: 2,
    name: 'File 1',
    folder:1
  },
  {
    id: 3,
    name: 'File 3',
    folder:1
  },
  {
    id: 4,
    name: 'File 2',
    folder:2
  },
  {
    id: 5,
    name: 'File 6',
    folder:2
  },
  {
    id: 6,
    name: 'File 4',
    folder:2
  }
];


App.Folder.FIXTURES = [
  { 
    id: 1,
    name: 'Folder 1',
    files:[1,2,3]
  },
  {
    id: 2,
    name: 'Folder 2',
    files:[4,5,6]
  }
];

Ваш шаблон:

<div>
   Folders: <br>
  <ul>
   <li>
     Name: {{model.name}} <br>
     Files:
     {{!-- here we access the sorted files property in the model--}}
     {{#each file in model.sortedFiles}}
       {{file.name}} <br/>
     {{/each}}
  </li>
 </ul>
</div>
person engma    schedule 19.06.2015
comment
Спасибо за советы. Я просмотрел так много файлов ember jsbins, что, должно быть, забыл про Ember-Data. Я обновил свой jsbin. Хотя на самом деле это ничего не изменило. sortedFiles: function(){ //Sorty By has no second parameter, if you need more sorting power, do it your self return this.get('files').sortBy('name'); }.property('[email protected]') это то, где у меня есть проблема. Я считаю, что версия emberjs, которую я использую, имеет sortBy, принимающую несколько аргументов. Но даже если я не использую sortBy, когда я использую обычную функцию сортировки, я не упорядочиваю файлы. Ничего не отображается. - person user2517182; 19.06.2015
comment
Я собираюсь пометить это как ответ, поскольку вы указали мне, что я должен выполнить сортировку «сам», если мне нужно больше возможностей сортировки, чем использование sortBy. Однако мое последнее обновление вопроса позволило мне использовать сортировку javascript по умолчанию и, таким образом, сделать это «сам». Если вы не возражаете, прокомментируйте, как я могу получить ваш код, который я скопировал и вставил для работы с jsbin. Или, пожалуйста, взгляните на мой другой вопрос stackoverflow.com/questions/30926167/ и дайте мне знать, как заставить приборы работать с jsbin. Спасибо еще раз. - person user2517182; 19.06.2015
comment
извините за поздний ответ, вот мой jsbin emberjs. jsbin.com/banozisuqa/1/edit?html,js,консоль,выход - person engma; 22.06.2015