sedovalx / taxi

6 stars 3 forks source link

Сделать список/редактор аренд #41

Closed kirzas closed 9 years ago

kirzas commented 9 years ago

Как для автомобилей, пользователей и проч.

kirzas commented 9 years ago

еще забыл вернуть кнопку удаления, которую убрал, следующим комитом верну.

sedovalx commented 9 years ago

@Argelein вроде норм, но нужно учитывать, что отображать в выпадающих списках нужно только водителей, для которых нет открытых аренд. Аналогично в выпадающем списке не должно быть машин, на которых уже кто-то ездит. Тут есть два подхода - делать такую фильтрацию на клиенте или на сервере. Если что-то сложное, и требующее загрузки большого кол-ва данных, то это нужно делать на сервере. Например, чтобы найти все свободные машины на клиенте, нужно будет

Это довольно много действий, которые при этом требуют загрузки немалого кол-ва данных. Правильно это делать на сервере, а на клиент передавать уже готовый массив свободных машин. Но пока мы это будем делать на клиенте. Делать это нужно в rent-controller.carItems сделать все вышеперечисленное. Учитывай, что все операции со store возвращают promise. Смотри так же вот это Примерно так:

Ember.RSVP.all(
    this.store.find("car"), 
    this.store.find("rent")
).then(function(resultsArray){
    let cars = resultArray[0];
    let rents = resultArray[1]; 
    let busyCarIds = rens.filter(rent => rent.get("state") !== <закрыто>)
                         .map(rent => rent.get("car").get("id"));
    return cars.filter(car => busyCarIds.indexOf(car.get("id")) < 0);
}).catch(function(error){
   // обработка ошибки 
});

Код написал, не проверяя. Для водителей аналогично. В javascript ты должен уметь пользоваться методами indexOf, filter и map у массивов, а так же знать, что такое Deferred/Promise. Без этого никуда.

kirzas commented 9 years ago

@sedovalx не могу справиться... Я там изменил кое-что, но ничего не заработало. Проверь, пожалуйста, как будет время, как должно работать:

carItems: function() {
    let model = this.get("model");
    return Ember.RSVP.Promise.all([
        model.store.find("car"),
        model.store.find("rent")]
    ).then(function(resultArray){
        let cars = resultArray[0]; 
        let rents = resultArray[1];
        let busyCarIds = rents.filter(rent => rent.get("status") !== "Closed")
          .map(rent => rent.get("car").get("id"));
        return cars.filter(car => busyCarIds.indexOf(car.get("id")) < 0);
      }).catch(function(error){
        //обработка ошибки
      });
  }.property("model"),
sedovalx commented 9 years ago

Проблема в том, что ember-selectize на вход (свойство content) ожидает объект, у которого есть все признаки массива, в том числе и метод addArrayObserver. Если его нет, то вылетает ошибка. EmberData при вызове метода store.find(...) возвращает объект DS.PromiseArray, который обладает всеми признаками массива. Однако, этот объект в тоже время является promise. Для ember-selectize это происходит совершенно прозрачно, и все работает. Но если мы начинаем работать с этим результатом как с promise, т.е. вызывать метод then, all и т.п., то результатом вызова этих методов будет уже обычное promise, которое не обладает признаками массива. Тут все и ломается.

sedovalx commented 9 years ago

@Argelein смотри комментарий выше и пример в коммите. С водителями в аренде аналогично.

sedovalx commented 9 years ago

На сервере:

  1. При создании аренды создавать запись в истории статусов
  2. При сериализации аренды в json вычислять актуальный статус
  3. При десериализации аренды из json извлекать статус, сравнивать его с актуальным из базы и, если они не равны, то создавать новую запись в истории статусов.