2016-12-20 3 views
6

У меня есть модель task, которая связана с моделями user и project.Картина для рендеринга нескольких кофе

Когда я создаю/обновляю задачу, мне нужно сделать обновление в представлении async не только для изменения/добавления задачи, но и для информации о проекте и пользователе (потому что некоторые из этих данных могут также измениться).

У меня есть это в контроллере:

def create 
    @task = Task.new(params[:task]) 
    @project = Project.find(params[:project_id]) 

    respond_to do |format| 
    if @task.save 
     format.html { redirect_to @task, notice: 'Task was successfully created.' } 
     format.json { render json: @task, status: :created, location: @task } 
    else 
     format.html { render action: "new" } 
     format.json { render json: @task.errors, status: :unprocessable_entity } 
    end 
    end 
end 

И мои задачи/create.js.coffee

# Update task table 
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>") 

# Update user data 
$('.user-data').html("<%= j render(partial: 'users/user_widget', locals: { u: current_user }) %>") 

# Update project data 
$('.project-data').html("<%= j render(partial: 'projects/project_widget', locals: { p: @project }) %>") 

И он прекрасно работает. Я вижу 2 вопроса:

  • В каждом рендер .js.coffee добавить, я повторяю код слишком много. Я дублирую точно такой же код для обновления данных проекта и пользователя, при обновлении задач, уничтожении задач, и я бы сделал то же самое для новой модели, которая может повлиять на пользователя и проект

  • Кажется странным обрабатывать проект и данные пользователя в задачах/create.js.coffee

Таким образом, я ищу лучший образец для обработки этого материала, любых идей?

EDIT (уточнить): Я думаю, что достижение что-то вроде этого было бы лучше:

задачи/create.js.coffee

# Update task table 
$('#mytable').append("<%= j render(partial: 'tasks/task', locals: { t: @task }) %>") 

UserData.refresh() 
ProjectData.refresh() 

Однако, я не могу сделать потому что мне нужно каждый раз отображать частицу, поэтому мне нужно было бы сделать что-то странное, как передать часть html тем функциям refresh(), и это было бы точно так же, как и предыдущий. Это только способ, который пришел мне на ум, но я хотел бы услышать ваши идеи, если они есть.

+0

Мне непонятно, что вы просите. Чего вы пытаетесь избежать? –

+0

Я стараюсь избегать этих двух проблем, которые я описываю на этом посту: Не повторяю код для обновления проекта и пользовательских данных в каждом кофе тех моделей, которые связаны с проектом и пользователем. И не имея ответственности за обновление пользователя и проекта в задаче js. Эти проблемы очень связаны, хотя –

+0

@DaveNewton См. Мое редактирование, это может немного прояснить ситуацию –

ответ

0

для тех, кто может быть заинтересован в ответе на этот вопрос, я нашел Гарбер-ирландский узор как отличное решение моей проблемы.

Вы можете прочитать об этом здесь: https://www.viget.com/articles/extending-paul-irishs-comprehensive-dom-ready-execution

Существует даже драгоценный камень: https://github.com/tonytonyjan/gistyle

Используя эту модель, вы можете иметь контексты выполнения для ваших HTTP-запросов. Например, вы можете использовать метод afterCreate() для каждого контроллера js и в зависимости от того, где был создан ваш HTTP-запрос, вы можете инициировать другое событие.

Это позволяет использовать полиморфные ответы для обновления вида.

1

Вы можете отобразить шаблон/действие, принадлежащее другому контроллеру. Таким образом, вы можете сохранить задачи/файл create.js.coffee и для всех других действий контроллера (например, пользователей и проектов), которые используют один и тот же код, в вашем respond_to блоке вы будете использовать:

format.json { render 'tasks/create' } 

Вы могли бы даже визуализации конкретного файла:

format.json { render file: "path/to/specific/file" } 

Вот ссылка с дополнительной информацией об оказании в рельсах: http://guides.rubyonrails.org/layouts_and_rendering.html#rendering-an-action-s-template-from-another-controller

+0

Я знаю это, но это не решит мою проблему, поскольку это то, что я делаю уже. Мой код выполняет задачу/create.js.coffee. Проблема в том, что этот файл заботится о нескольких обновлениях просмотра, которые не полностью связаны с задачей. Однако, большое спасибо за вашу помощь –

+1

Извините за недоразумение. Единственный способ, с которым я могу с этим справиться, - это ответить контроллеру на json-информацию (вместо рендеринга javascript) и использовать обратный вызов jQuery ajax для обновления информации на странице. Тогда у вас будет один файл для обработки всех обновлений страницы. Вы даже можете создавать общие функции, такие как 'UserData.refresh()' и 'ProjectData.refresh()', но все это в javascript, а не через рендеринг контроллера. Я не думаю, что вы делаете это сейчас, это плохо или нетрадиционно, это просто другие варианты. – farrows76