Подтвердить что ты не робот

EmberJS - обмен контроллером/шаблоном для разных маршрутов

У меня очень простое приложение CRUD, которое позволяет создавать новые объекты, а также редактировать их.

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

Они используют те же самые элементы формы. Единственное различие заключается в названии и кнопке под формой (которая должна либо обновлять, либо создавать запись)

В моей реализации у меня есть

  • 2 определения маршрута
  • 2 объекта маршрута
  • 2 объекта контроллера
  • 2 шаблона

Мне было интересно, если

  • Я не могу рекламировать повторное использование здесь.
  • если требуются все эти объекты.

Что меня беспокоит:

  • У меня есть два отдельных шаблона для создания и редактирования (хотя они почти идентичны)
  • У меня есть 2 отдельных контроллера, которые делают то же самое.

Я надеялся решить эту проблему на уровне контроллера. Поскольку контроллер украшает модель, в моем случае один объект одного контроллера может обернуть либо новую запись, либо существующую запись. Затем он может открыть свойство (isNewObject), чтобы шаблон мог решить, находимся ли мы в потоке "новый" или "редактировать". Контроллер может иметь один метод createOrUpdate, который работает как в сценарии new, так и в update.

Маршруты

В текущей реализации используется новый и редактируемый маршрут для моего ресурса.

this.resource("locations", function(){
  this.route("new", {path:"/new"});
  this.route("edit", {path: "/:location_id" });
});

Новый маршрут

new route отвечает за создание новой записи и вызывается, когда пользователь переходит к новому экрану записи.

App.LocationsNewRoute = Ember.Route.extend({
  model: function() {
    return App.Location.createRecord();
  }
});

Маршрут редактирования

edit route отвечает за редактирование существующего объекта, когда пользователь нажимает кнопку редактирования на обзорном экране. Я не расширил маршрут редактирования по умолчанию, но вместо этого я использую автоматически сгенерированный файл.

Контроллеры

Контроллеры new и edit отвечают за обработку действия, которое происходит в шаблоне (сохранение или обновление записи)

Единственное, что делают оба контроллера - это совершить транзакцию.

Примечание: Я предполагаю, что это кандидат на повторное использование, но как я могу использовать один контроллер для управления двумя разными маршрутами/шаблонами?

App.LocationsNewController = Ember.ObjectController.extend({
  addItem: function(location) {
    location.transaction.commit();
    this.get("target").transitionTo("locations");
  }
});

App.LocationsEditController = Ember.ObjectController.extend({
  updateItem: function(location) {
    location.transaction.commit();
    this.get("target").transitionTo("locations");
  }
});

Шаблоны:

Как вы можете видеть, единственное повторное использование кода, которое у меня есть, это частичное (привязка поля модели). У меня все еще есть 2 контроллера (новые и редактировать) и 2 шаблона.

Новые шаблоны устанавливают правильную кнопку title/и повторно используют форму.

<script type="text/x-handlebars" data-template-name="locations/new" >
    <h1>New location</h1>
    {{partial "locationForm"}}
    <p><button {{action addItem this}}>Add record</button></p>
</script>

Шаблоны редактирования устанавливают правильную кнопку title/и повторно используют форму.

<script type="text/x-handlebars" data-template-name="locations/edit" >
    <h1>Edit location</h1>
    {{partial "locationForm"}}
    <p><button {{action updateItem this}}>Update record</button></p>
</script>

Частичный

<script type="text/x-handlebars" data-template-name="_locationForm" >
  <form class="form-horizontal">
  <div class="control-group">
    <label class="control-label" for="latitude">Latitude</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="latitude"}}
    </div>
  </div>
  <div class="control-group">
    <label class="control-label" for="latitude">Longitude</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="longitude"}}
    </div>
  </div>
  <div class="control-group">
    <label class="control-label" for="accuracy">Accuracy</label>
    <div class="controls">
      {{view Ember.TextField valueBinding="accuracy"}}
    </div>
  </div>
</form>
</script>

Примечание: Я бы ожидал, что я могу сделать что-то эффективное/умнее.

Я бы хотел, чтобы мой шаблон выглядел так: (получая заголовок от контроллера и имеющее одно действие, которое обрабатывает как обновление, так и создание)

<script type="text/x-handlebars" data-template-name="locations" >
    <h1>{{title}}</h1>
    {{partial "locationForm"}}
    <p><button {{action createOrUpdateItem this}}>Add record</button></p>
</script>

Вопрос

Могу ли я переработать этот код, чтобы иметь больше повторного использования кода, или это плохая идея, чтобы попытаться сделать это с помощью одного шаблона и одного контроллера для потоков "редактирования записи" и "новой записи". Если да, то как это можно сделать? Мне не хватает части, в которой мои 2 маршрута (создание и редактирование) будут повторно использовать один и тот же контроллер/шаблон.

4b9b3361

Ответ 1

Вы были верны во всем.

И вы также можете использовать новый контроллер и шаблон в edit route.

Вы должны сделать только две вещи.

Сначала укажите имя шаблона как новое в renderTemplate hook edit route.

App.LocationsEditRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    this.controllerFor('locations.new').setProperties({isNew:false,content:model});
  },
  renderTemplate: function() {
    this.render('locations/new')         
  }
});

По мере создания нового шаблона контроллер также будет newController, и вы можете заставить действие указать событие в newController.

Если вы хотите изменить текст заголовка и кнопки, вы можете получить их в качестве вычисленных свойств, соблюдая свойство isNew.

Надеюсь, что это поможет.

P.S: Не забудьте установить для свойства isNew значение true в setupController new route

Ответ 2

Используйте это:

App.YourNewRoute = Em.Route.extend ({
   controllerName: 'controllerName',
   templateName: 'templateName'
 });

Используйте только начальное имя, например, для пользователя homeController "home".

Пример:

App.YourNewRoute =  Em.Route.extend ({
   controllerName: 'home',
   templateName: 'home'
});

Теперь вы можете использовать методы шаблона и контроллера для "дома".