Phoenix, используя сокеты и Presence вне socket.js, в шаблонах eex - PullRequest
0 голосов
/ 12 июня 2018

Я хочу организовать использование socket и Presence в шаблоне по-своему.Как новичку, мне кажется, что помещение всего клиентского кода, имеющего дело с каналами, в sockets.js может преобразовать его в очень большой кусок.Особенно, если есть много страниц, которые используют сокеты / Присутствие.Я не знаю, какое решение является наилучшим (или если это проблема для других людей), но мое неправильно понятое функционирование js приводит меня к правильной организации кода.

В socket.js

    import {Socket, Presence} from "phoenix"
    // Other stuff
    export {
      Presence,
      socket
    }

В app.js вместо import socket from "./socket" в конце я пишу

import {Presence, socket} from "./socket"

window.getPhoenixSocket = function () {
    return socket;
};
window.getPhoenixPresence = function () {
    return Presence;
};

И в шаблоне eex (я знаю, что не рекомендуется смешивать html и сценарии)(за исключением ребят из React!) Я пишу следующий скрипт:

<script>
  window.onload = function () {
    let channel = getPhoenixSocket (). channel ("cute: channel", {})
    let Presence = getPhoenixPresence ();
....
// Here I can use channel and Presence for my obscure purposes
....
}
</script>

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

AsЯ не совсем доволен этим решением, я спрашиваю вас, это правильно?Не так ли?Каков будет лучший способ сделать это?Есть ли кто-то, кто имеет эту проблему?

===== РЕДАКТИРОВАТЬ ======

РЕШЕНИЕ1:

Четкий, умный, добрый и полный ответ имеетбыл разоблачен perereynders в elixirforum

SOLUTION2:

Другое решение, на которое указывает Деини в Slack Channel Эликсира-Ланга, снова используя Webpack,и включает в себя гораздо больше стиля феникс-эликсир, был опубликован hoang_nguyen на Medium .

SOLUTION3:

Использование Brunch и использование Webpack в Diacode и второй странице здесь

1 Ответ

0 голосов
/ 13 июня 2018

Выбранное решение состоит из нескольких частей и, как указано в diacode , с небольшими изменениями может быть применено в будущем Webpack в Фениксе> = 1.4.

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

Имя создается в функции в layout_view.ex и помещается в качестве атрибута в * 1008.* тег app.html.eex примерно так:

<body data-js-view-name="<%= js_view_name(@view_module, @view_template) %>">

Затем app.js несет ответственность за загрузку конкретных js для каждого шаблона, который мы поместили в assests/js/views, и вызывает вызовфункция.

import loadView from './views/view_loader';

function handleDOMContentLoaded() {
  //// Get the current view name
  const viewName = document.getElementsByTagName('body')[0].dataset.jsViewName;
  // Load view class and mount it
  const ViewClass = loadView(viewName);

  window.currentView = new ViewClass();
  window.currentView.mount();
}

function handleDocumentUnload() {
  window.currentView.unmount();
}

window.addEventListener('DOMContentLoaded', handleDOMContentLoaded, false);
window.addEventListener('unload', handleDocumentUnload, false);

Загрузчик представления:

    import MainView    from './main';
    import RoomShowView from './room_show';
    import UserShowView from './user_show';

    // Collection of specific view modules
    const views = {
      "room_show": RoomShowView,
      "user_show": UserShowView
    };

    export default function loadView(viewName) {
      return views[viewName] || MainView;
    }

на данный момент, вы должны импортировать представления (это изменится с Webpack)

структура каждого js-файла представляет собой пару функций mount и unmount (по умолчанию вызывающих родительский вид), в которые мы помещаем наш код.

import MainView from './main';
import socket from "../socket";
import {Presence} from "phoenix";

export default class View extends MainView {
  mount() {
    super.mount();
    // the code
    console.log('room-show mounted');
    console.log('eex room.id: '+eex["@room.id"])
  }

  unmount() {
    super.unmount();

    // Specific logic here
    console.log('room-show unmounted');
  }
}

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

<script>
var eex = {
  "@room.id": <%= @room.id %>,
  "@current_user.name": "<%= @current_user.name %>",
  "@current_user.id": <%= @current_user.id %>
}
</script>

Идея заключалась в том, чтобы использовать один канал только в одном шаблоне и поддерживать другой канал для общих целей всех шаблонов.Канал создается в app.js, и вы можете push, в любом другом шаблоне, я поместил его в main.js

Я опускаю код, так как он находится в ссылке, и я уверен,Вы видели это где-то еще.

Еще многое предстоит сделать, это незавершенный код.Но там есть на GitHub

...