Un módulo para crear módulos acoplados de CSS, JavaScript y Vistas en Phoenix.
Agregue lo siguiente a las dependencias en mix.exs :
{ :ex_cell , "~> 0.0.14" } En Phoenix 1.3.0+, agregue lo siguiente a lib/app_web/web.ex :
def controller do
quote do
...
import ExCell.Controller
...
end
end
def view ( opts \ [ ] ) do
quote do
...
import ExCell.View
...
end
end
def cell ( opts \ [ ] ) do
quote do
use ExCell.Cell , namespace: AppWeb ,
adapter: ExCell.Adapters.CellJS
use Phoenix.View , root: "lib/app_web/cells" ,
path: ExCell.View . relative_path ( __MODULE__ , AppWeb )
import Phoenix.Controller ,
only: [ get_csrf_token: 0 , get_flash: 2 , view_module: 1 ]
use Phoenix.HTML
import AppWeb.Router.Helpers
import AppWeb.Gettext
# Add everything you want to use in the cells
end
endAhora puede agregar un directorio/ directorio en lib/ app_web y colocar celdas en ese directorio.
Cada celda debe contener una vista.ex y una plantilla.html.Eex. La vista y la plantilla están estrechamente unidas por la celda.
Para asegurarse de que se pueda colocar todo el CSS al lado de su celda, debe agregar lo siguiente a su brunch-config.js :
...
stylesheets : {
joinTo : {
"css/app.css" : [
"assets/css/app.css" ,
"lib/app_web/cells/**/*.css"
]
}
}
. . .Si usa algo más que brunch para administrar sus activos, debe agregar los archivos al Administrador de activos de elección.
Si desea utilizar la biblioteca Cell-JS de acompañamiento, puede instalarla con su Administrador de paquetes. Después de instalar el paquete JavaScript, agregue lo siguiente a su brunch-config.js :
...
javascripts : {
joinTo : {
"js/vendor.js" : / ^node_modules / ,
"js/app.js" : [
"assets/js/**/*.js" ,
"lib/app_web/cells/**/*.js"
]
}
}
. . . Una celda consta de un par de archivos:
cells
|- avatar
| |- template.html.eex
| |- view.ex
| |- style.css (optional)
| |- index.js (optional)
|- header
...
Puede representar la celda en una vista, controlador u otra celda agregando el siguiente código:
cell ( AvatarCell , class: "CustomClassName" , user: % User { } )Esto generaría el siguiente HTML cuando rinde la celda:
< span class =" AvatarCell " data-cell =" AvatarCell " data-cell-params =" {} " >
< img src =" /images/foo/avatar.jpg " class =" AvatarCell-Image " alt =" foo " />
</ span >Las vistas de las células se comportan como vistas normales en Phoenix, excepto que han proporcionado un método de contenedor que puede usarse en una plantilla para representar el HTML apropiado necesario para inicializar el JavaScript para una celda y tener una clase predefinida que sea la misma que el nombre de la celda menos el espacio de nombres.
# lib/app_web/cell/avatar/view.ex
defmodule AppWeb.AvatarCell do
@ moduledoc """
The avatar cell used to render the user avatars.
"""
use AppWeb , :cell
alias App.Accounts.Avatar
def class_names ( assigns ) do
[ assigns [ :class ] , class_name ( assigns [ :size ] ) ]
|> Enum . reject ( fn ( v ) -> is_nil ( v ) end )
end
def avatar_image_path ( user ) do
Avatar . url ( { user . avatar , user } , :thumb )
end
def avatar_image_alt ( user ) do
[ user . first_name , user . last_name ]
|> Enum . join ( " " )
|> String . trim ( )
end
endLa plantilla se comporta como cualquier otra plantilla en Phoenix, excepto que tienen acceso a un método de contenedor para representar el contenedor HTML de celda apropiado:
<!-- lib/app_web/cell/avatar/template.html.eex -->
<%= container ( tag: :span , class: class_names (assigns)) do % >
<%= if image_path = avatar_image_path ( @user ) do % >
<%= img_tag (image_path, class: class_name ( " image " ), alt: avatar_image_alt ( @user )) % >
<% end % >
<% end % >Este puede ser cualquier tipo de archivo CSS que desee (preprocesado u otro sabio). Debido a que las celdas proporcionan métodos para el espacio de nombres de su CSS, se le recomienda que use un espacio de nombres similar o use algo como PostCSS-Modules para garantizar que todas las clases definidas sean únicas.
/* lib/app_web/cell/avatar/style.css */
. AvatarCell {
border-radius : 50 % ;
height : 50 px ;
width : 50 px ;
}
. AvatarCell-image {
display : inline-block;
max-width : 100 % ;
}Si usa Cell-JS, puede crear JavaScript que esté bien acoplado a la celda:
// lib/app_web/cells/avatar/index.js
import { Cell , Builder } from "@defacto/cell-js" ;
class AvatarCell extends Cell {
initialize ( ) {
this . element . addEventListener ( "click" , this . onToggleOpenClass ) ;
}
onToggleOpenClass = e => this . element . classList . toggle ( "open" ) ;
}
Builder . register ( AvatarCell , "AvatarCell" ) ;
export default AvatarCell ; Para células anidadas (por ejemplo, AppWeb.User.AvatarCell ) Asegúrese de incluir el espacio de nombres en la hoja de estilo/javascript.
. User-AvatarCell {} Builder . register ( AvatarCell , "User-AvatarCell" ) ; En caso de duda, el nombre de la celda corresponde al atributo data-cell en el elemento DOM.