시약을위한 양식 데이터 바인딩을 제공하기위한 clojurescript 라이브러리는 라이브 데모에 대해서는 여기를 참조하십시오.
라이브러리는 시약 원자를 문서 저장소로 사용합니다. 구성 요소는 :field 을 사용하여 문서에 바인딩됩니다. 이 키는 특정 유형의 구성 요소가 어떻게 결합되어야하는지 결정하는 데 사용됩니다. 구성 요소는 또한이를 문서와 상관시키는 데 사용되는 고유 한 :id 속성을 제공해야합니다. 라이브러리는 Twitter Bootstrap을 사용하여 사용하기 위해 사용되지만 생성 한 구성 요소 유형에 대해 상당히 불가지론 적입니다.
:id 키워드 (예 : {:id :foo} 또는 {: {:foo {:bar "value"}} {:id :foo.bar} 일 수 있습니다. 또는 벡터 경로를 명시 적으로 지정할 수 있습니다 [:foo 0 :bar] .
기본적으로 구성 요소 값은 문서 필드의 :in-fn 값이지만 모든 구성 요소는 :out-fn 을 지원합니다. :in-fn 현재 문서 값을 수락하고 구성 요소에 표시 할 내용을 반환합니다. :out-fn 구성 요소 값을 수락하고 문서에 저장 될 내용을 반환합니다.
다음 유형의 필드는 상자에서 지원됩니다.
입력 필드는 유형 일 수 있습니다 :text , :numeric , :range , :password , :email , :textarea . 입력은 정기적 인 HTML 입력과 마찬가지로 동작하고 :on-change 이벤트가 트리거 될 때 문서 상태를 업데이트합니다.
[ :input.form-control { :field :text :id :first-name }]
[ :input.form-control { :field :numeric :id :age }] 입력 필드는 값에 대한 형식 문자열을 제공 할 수있는 선택 사항 :fmt 속성을 가질 수 있습니다.
[ :input.form-control
{ :field :numeric :fmt " %.2f " :id :bmi :disabled true }]숫자 입력은 HTML 5 숫자 입력의 속성을 지원합니다.
[ :input
{ :field :numeric
:id :volume
:fmt " %.2f "
:step " 0.1 "
:min 0
:max 10 }] TypeAhead 필드는 A :data-source 키를 사용하여 현재 입력을 취하고 일치하는 결과 목록을 반환하는 함수에 바인딩됩니다. 컨트롤은 입력 요소를 사용하여 사용자 입력을 처리하고 하나 이상의 목록 항목 요소를 포함하는 정렬되지 않은 목록 요소로 선택 목록을 렌더링합니다. 사용자는 키를 사용하여 각 요소를 렌더링하는 데 사용되는 CSS 클래스를 지정할 수 있습니다. 입력 클래스, : List-Class 및 : 항목 클래스. 사용자는 다음과 같이 CSS 클래스를 추가로 지정하여 다음과 같은 하이라이트 클래스 키를 사용하여 현재 선택의 하이라이트를 처리 할 수 있습니다. 참조 CSS 클래스는 리소스/public/css/reagent-forms.css 파일에 포함됩니다.
( defn friend-source [text]
( filter
#( -> % ( .toLowerCase %) ( .indexOf text) ( > -1 ))
[ " Alice " " Alan " " Bob " " Beth " " Jim " " Jane " " Kim " " Rob " " Zoe " ]))
[ :div { :field :typeahead
:id :ta
:input-placeholder " pick a friend "
:data-source friend-source
:input-class " form-control "
:list-class " typeahead-list "
:item-class " typeahead-item "
:highlight-class " highlighted " }]TypeAhead 필드는 마우스 및 키보드 선택을 모두 지원합니다.
입력의 표시된 값을 문서에 저장된 값과 다르게 만들 수 있습니다. 다음을 지정해야합니다 :out-fn , A :result-fn 및 선택적으로 :in-fn . :data-source 벡터를 반환해야합니다 [display-value stored-value] .
( defn people-source [people]
( fn [text]
( ->> people
( filter #( -> ( :name %)
( .toLowerCase )
( .indexOf text)
( > -1 )))
( mapv #( vector ( :name %) ( :num %))))))
[ :div { :field :typeahead
:data-source ( people-source people)
:in-fn ( fn [num]
[( :name ( first ( filter #( = num ( :num %)) people))) num])
:out-fn ( fn [[name num]] num)
:result-fn ( fn [[name num]] name)
:id :author.num }]]] if :data-source 키워드를 전달할 때 전체 옵션 목록으로 응답합니다 :all 다운 아로우 키가 목록을 표시합니다.
:selections 속성을 지정하여 선택을 유지하는 데 사용되는 원자를 전달할 수 있습니다. 이렇게하면 Typeahead 텍스트를 사용하여 목록을 가져 오는 옵션이 제공됩니다. AJAX 응답 핸들러가 원자를 설정하면 목록이 팝업됩니다.
제공되면 :get-index 함수는 목록이 팝업 될 때 선택한 항목이 강조 표시되도록합니다.
시연 페이지의 소스 코드에서 전체 예제를 사용할 수 있습니다.
Checkbox 필드는 확인란 요소를 만듭니다.
[ :div.row
[ :div.col-md-2 " does data binding make you happy? " ]
[ :div.col-md-5
[ :input.form-control { :field :checkbox :id :happy-bindings }]]] 확인란은 선택 사항을 허용합니다 :checked 속성. 설정하면 확인란이 선택되고 다음과 같이 지적 된 문서 경로가 표시됩니다 :id 키는 true 로 설정됩니다.
[ :div.row
[ :div.col-md-2 " does data binding make you happy? " ]
[ :div.col-md-5
[ :input.form-control { :field :checkbox :id :happy-bindings :checked true }]]] Range Control을 사용합니다 :min 및 :max 키를 사용하여 HTML 범위 입력을 만듭니다.
[ :input.form-control
{ :field :range :min 10 :max 100 :id :some-range }] 라디오 버튼은 다음을 사용하지 않으며 :id 키는 고유해야하며 다음을 사용하여 그룹화되므로 :name 속성을 사용하여 그룹화됩니다. :value 속성은 문서에 저장된 값을 나타내는 데 사용됩니다.
[ :input { :field :radio :value :a :name :radioselection }]
[ :input { :field :radio :value :b :name :radioselection }]
[ :input { :field :radio :value :c :name :radioselection }] 라디오 버튼은 선택 사항 :checked 속성을 허용합니다. 설정하면 확인란이 선택되고 다음과 같이 지적 된 문서 경로가 표시됩니다 :name 키는 true 로 설정됩니다.
[ :input { :field :radio :value :a :name :radioselection }]
[ :input { :field :radio :value :b :name :radioselection :checked true }]
[ :input { :field :radio :value :c :name :radioselection }] 파일 필드는 <input type="file"/> 의 File 개체를 바인딩합니다.
[ :input { :field :file :type :file }] <input type="file" multiple/> 에서 작동하고 전체 FileList 객체를 바인딩하는 것을 제외하고는 파일과 동일합니다.
[ :input { :field :files :type :file :multiple true }] 목록 필드에는 선택시 문서에 값이 채워진 자식 요소가 포함되어 있습니다. 자식 요소는 각각 다음을 있어야합니다 :key 속성이 있어야합니다. 요소의 값은 키워드 여야합니다.
요소는 선택 사항을 가질 수 있습니다 :visible? 술어 기능을 가리키는 키워드. 함수는 문서를 수락하고 필드를 표시 해야하는지 표시하는 부울 값을 반환해야합니다.
:list Field는 option 자식 요소를 포함하는 HTML select 요소를 작성하는 데 사용됩니다.
[ :select.form-control { :field :list :id :many-options }
[ :option { :key :foo } " foo " ]
[ :option { :key :bar } " bar " ]
[ :option { :key :baz } " baz " ]]
( def months
[ " January " " February " " March " " April " " May " " June "
" July " " August " " September " " October " " November " " December " ])
[ :select { :field :list :id :dob.day }
( for [i ( range 1 32 )]
[ :option
{ :key ( keyword ( str i))
:visible? #( let [month ( get-in % [ :dob :month ])]
( cond
( < i 29 ) true
( < i 31 ) ( not= month :February )
( = i 31 ) ( some #{month} [ :January :March :May :July :August :October :December ])
:else false ))}
i])]
[ :select { :field :list :id :dob.month }
( for [month months]
[ :option { :key ( keyword month)} month])]
[ :select { :field :list :id :dob.year }
( for [i ( range 1950 ( inc ( .getFullYear ( js/Date. ))))]
[ :option { :key ( keyword ( str i))} i])]단일 선택 필드는 목록처럼 작동하지만 다양한 유형의 요소를 지원하고 필드를 선택치 할 수 있습니다.
[ :h3 " single-select buttons " ]
[ :div.btn-group { :field :single-select :id :unique-position }
[ :button.btn.btn-default { :key :left } " Left " ]
[ :button.btn.btn-default { :key :middle } " Middle " ]
[ :button.btn.btn-default { :key :right } " Right " ]]
[ :h3 " single-select list " ]
[ :ul.list-group { :field :single-select :id :pick-one }
[ :li.list-group-item { :key :foo } " foo " ]
[ :li.list-group-item { :key :bar } " bar " ]
[ :li.list-group-item { :key :baz } " baz " ]]다중 선택 필드를 사용하면 여러 값을 선택하고 문서에서 설정할 수 있습니다.
[ :h3 " multi-select list " ]
[ :div.btn-group { :field :multi-select :id :position }
[ :button.btn.btn-default { :key :left } " Left " ]
[ :button.btn.btn-default { :key :middle } " Middle " ]
[ :button.btn.btn-default { :key :right } " Right " ]] 라벨은 :id 을 사용하여 문서의 키와 연관 될 수 있으며 해당 키의 값을 표시합니다. lables는 옵션을 가질 수 있습니다 :preamble 및 :postamble 블 키. 값은 다음과 :fmt 키에 할당 된 Formatter 함수를 사용하여 해석 할 수 있습니다. :placeholder 자 키는 값이없는 경우 표시 될 텍스트를 제공하는 데 사용될 수 있습니다.
[ :label { :field :label :id :volume }]
[ :label { :field :label :preamble " the value is: " :id :volume }]
[ :label { :field :label :preamble " the value is: " :postamble " ml " :id :volume }]
[ :label { :field :label :preamble " the value is: " :postamble " ml " :placeholder " N/A " :id :volume }]
[ :label { :field :label :preamble " the value is: " :id :volume :fmt ( fn [v] ( if v ( str v " ml " ) " unknown " )}] 알림은 경고를 트리거하고 선택 사항을 가질 수있는 필드의 ID에 바인딩됩니다 :event 키. 이벤트 키는 부울 값을 반환하는 함수를 가리켜 야합니다.
선택 사항 :closeable? true/false 닫기 버튼을 렌더링 해야하는 경우 (기본값으로 참조) :closeable? true/false 제공 될 수 있습니다.
이벤트가 제공되면 이벤트가 참을 때마다 경고의 본문이 렌더링됩니다.
[ :input { :field :text :id :first-name }]
[ :div.alert.alert-success { :field :alert :id :last-name :event empty?} " first name is empty! " ]이벤트가 제공되지 않으면 ID의 값이 비어 있지 않고 값을 표시 할 때마다 경고가 표시됩니다.
( def doc ( atom {}))
; ;define an alert that watches the `:errors.first-name` key for errors
[ :div.alert.alert-danger { :field :alert :id :errors.first-name }]
; ;trigger the alert by setting the error key
[ :button.btn.btn-default
{ :on-click
#( if ( empty? ( :first-name @doc))
( swap! doc assoc-in [ :errors :first-name ] " first name is empty! " ))}
" save " ][ :div { :field :datepicker :id :birthday :date-format " yyyy/mm/dd " :inline true }]날짜는 다음 형식을 사용하여 문서에 저장됩니다.
{ :year 2014 :month 11 :day 24 } DatePicker는 선택 사항을 선택할 수 있습니다 :auto-close? 키는 하루를 클릭하면 닫아야한다는 것을 나타냅니다. 이것은 기본값으로 false 만듭니다.
날짜 형식은 다음을 사용하여 설정할 수 있습니다 :date-format 키 :
{ :field :datepicker :id :date :date-format " yyyy/mm/dd " } :date-format 형식 날짜를 반환하는 함수를 가리킬 수 있습니다.
{ :field :datepicker
:id :date
:date-format ( fn [{ :keys [year month day]}] ( str year " / " month " / " day))} 위의 것은 값을 저장하기 위해 사용자 정의 기능을 제공 할 수있는 :save-fn 키와 함께 유용합니다. 예를 들어 JavaScript 날짜 개체를 사용하려면 다음을 수행 할 수 있습니다.
[ :div.input-group.date.datepicker.clickable
{ :field :datepicker
:id :reminder
:date-format ( fn [date]
( str ( .getDate date) " / "
( inc ( .getMonth date)) " / "
( .getFullYear date)))
:save-fn ( fn [current-date { :keys [year month day]}]
( if current-date
( doto ( js/Date. )
( .setFullYear year)
( .setMonth ( dec month))
( .setDate day)
( .setHours ( .getHours current-date))
( .setMinutes ( .getMinutes current-date)))
( js/Date. year ( dec month) day)))
:auto-close? true }]구성 요소가 다시 Repaint에 새 날짜 객체를 업데이트로 반환해야합니다.
DatePicker는 선택 사항을 취합니다 :lang Key는 DatePicker의 로케일을 설정하는 데 사용할 수 있습니다. 현재 영어, 러시아어, 독일어, 프랑스어, 스페인어, 포르투갈어, 핀란드어 및 네덜란드어는 번역이 있습니다. 내장 언어 패스를 사용하려면 :lang :
| 언어 | 예어 |
|---|---|
| 영어 | :en-US (기본값) |
| 러시아인 | :ru-RU |
| 독일 사람 | :de-DE |
| 프랑스 국민 | :fr-FR |
| 스페인 사람 | :es-ES |
| 포르투갈 인 | :pt-PT |
| 핀란드 | :fi-FI |
| 네덜란드 사람 | :nl-NL |
내장 언어 로케일 사용의 예 :
{ :field :datepicker :id :date :date-format " yyyy/mm/dd " :inline true :lang :ru-RU } DatePicker에 맞춤형 로케일 해시 맵을 제공 할 수도 있습니다. :first-day 일요일부터 시작하는 첫 번째 요일을 0으로 표시합니다. 모든 키는 지정되어야합니다.
사용자 정의 로케일 해시 맵 사용 예 :
{ :field :datepicker :id :date :date-format " yyyy/mm/dd " :inline true :lang
{ :days [ " First " " Second " " Third " " Fourth " " Fifth " " Sixth " " Seventh " ]
:days-short [ " 1st " " 2nd " " 3rd " " 4th " " 5th " " 6th " " 7th " ]
:months [ " Month-one " " Month-two " " Month-three " " Month-four " " Month-five " " Month-six "
" Month-seven " " Month-eight " " Month-nine " " Month-ten " " Month-eleven " " Month-twelve " ]
:months-short [ " M1 " " M2 " " M3 " " M4 " " M5 " " M6 " " M7 " " M8 " " M9 " " M10 " " M11 " " M12 " ]
:first-day 0 }} DatePicker는 올바르게 렌더링하기 위해 추가 CSS가 필요합니다. 기본 CSS는 리소스 경로의 reagent-forms.css 에 제공됩니다. 페이지에 포함되어 있는지 확인하십시오. 파일은 다음을 사용하여 읽을 수 있습니다.
( -> " reagent-forms.css " clojure.java.io/resource slurp)컨테이너 요소는 다른 요소를 그룹화하는 데 사용할 수 있습니다. 컨테이너를 사용하여 여러 요소의 가시성을 설정할 수 있습니다.
[ :div.form-group
{ :field :container
:visible? #( :show-name? %)}
[ :input { :field :text :id :first-name }]
[ :input { :field :text :id :last-name }]] :validator Keyword를 사용하여 Validator 함수를 구성 요소에 연결할 수 있습니다. 이 기능은 문서의 현재 상태를 수락하고 요소에 추가 될 클래스 모음을 반환합니다.
[ :input
{ :field :text
:id :person.name.first
:validator ( fn [doc]
( when ( -> doc :person :name :first empty?)
[ " error " ]))}] 구성 요소는 선택 사항을 제공 할 수 있습니다 :visible? 결정 기능을 가리키는 속성의 키. 함수는 문서의 현재 값을 취하고 구성 요소를 렌더링 해야하는지 여부를 결정하는 데 사용될 진실 값을 생성 할 것으로 예상됩니다.
( def form
[ :div
[ :input { :field :text
:id :foo }]
[ :input { :field :text
:visible? ( fn [doc] ( empty? ( :foo doc)))
:id :bar }]]) :set-attributes 키는 구성 요소의 속성에 대해 임의의 업데이트를 수행 해야하는 경우 사용할 수 있습니다. 키는 문서의 현재 값과 구성 요소의 속성 맵을 받아들이는 함수를 가리켜 야합니다. 함수는 업데이트 된 속성 맵을 반환해야합니다.
[ :div
[ :input { :field :text
:id :person.name.first
:validator ( fn [doc]
( when ( = " Bob " ( -> doc :person :name :first ))
[ " error " ]))}]
[ :input { :field :text
:id :person.name.last
:set-attributes ( fn [doc attrs]
( assoc attrs :disabled ( = " Bob " ( -> doc :person :name :first ))))}]]위의 예는 이름 입력의 값이 "bob"인 경우 성 입력을 비활성화합니다.
현장 구성 요소는 다른 시약 구성 요소와 마찬가지로 동작하며 자유롭게 혼합 할 수 있습니다. 완전한 양식 예제는 아래에서 볼 수 있습니다.
형태 요소는 사용하여 중첩 구조에 결합 할 수 있습니다 . 경로 분리기로. 예를 들어, 다음 구성 요소 [:input {:field :text :id :person.first-name}] 상태 원자 {:person {:first-name <field-value>}} 의 다음 경로에 바인딩됩니다.
( defn row [label input]
[ :div.row
[ :div.col-md-2 [ :label label]]
[ :div.col-md-5 input]])
( def form-template
[ :div
( row " first name " [ :input { :field :text :id :first-name }])
( row " last name " [ :input { :field :text :id :last-name }])
( row " age " [ :input { :field :numeric :id :age }])
( row " email " [ :input { :field :email :id :email }])
( row " comments " [ :textarea { :field :textarea :id :comments }])])중요한 메모
템플릿은 열심히 평가되며, 벡터에 넣는 대신 위의 예에서와 같이 항상 도우미 기능을 호출해야합니다. bind-fields 템플릿을 컴파일하도록 호출되면 시약 성분으로 대체됩니다.
양식 템플릿이 만들어지면 bind-fields 함수를 사용하여 문서에 바인딩 될 수 있습니다.
( ns myform.core
( :require [reagent-forms.core :refer [bind-fields]]
[reagent.core :as r]))
( defn form []
( let [doc ( r/atom {})]
( fn []
[ :div
[ :div.page-header [ :h1 " Reagent Form " ]]
[bind-fields form-template doc]
[ :label ( str @doc)]])))
( reagent/render-component [form] ( .getElementById js/document " container " ))양식은 인구가있는 문서로 초기화 될 수 있으며 필드는 그곳에서 발견 된 값으로 초기화됩니다.
( def form-template
[ :div
( row " first name "
[ :input.form-control { :field :text :id :first-name }])
( row " last name "
[ :input.form-control { :field :text :id :last-name }])
( row " age "
[ :input.form-control { :field :numeric :id :age }])
( row " email "
[ :input.form-control { :field :email :id :email }])
( row " comments "
[ :textarea.form-control { :field :textarea :id :comments }])])
( defn form []
( let [doc ( atom { :first-name " John " :last-name " Doe " :age 35 })]
( fn []
[ :div
[ :div.page-header [ :h1 " Reagent Form " ]]
[bind-fields form-template doc]
[ :label ( str @doc)]]))) bind-fields 함수는 선택적 이벤트를 수락합니다. 이벤트는 문서가 업데이트 될 때마다 트리거되며 나열된 순서대로 실행됩니다. 각 이벤트는 이전 모델이 수정 한 문서를 봅니다.
이벤트는 id , path , value 및 document 인 3 개의 매개 변수를 취해야합니다. id 필드의 :id 일치하고, path 문서의 필드 경로이고, value 양식에서 변경된 값을 나타내며, 문서에는 양식의 상태가 포함되어 있습니다. 이벤트는 업데이트 된 문서를 반환하거나 nil nil 할 수 있습니다.
다음은 :bmi 키 :weight 값을 계산하는 이벤트의 예입니다 :height
( defn row [label input]
[ :div.row
[ :div.col-md-2 [ :label label]]
[ :div.col-md-5 input]])
( def form-template
[ :div
[ :h3 " BMI Calculator " ]
( row " Height " [ :input { :field :numeric :id :height }])
( row " Weight " [ :input { :field :numeric :id :weight }])
( row " BMI " [ :input { :field :numeric :id :bmi :disabled true }])])
[bind-fields
form-template
doc
( fn [id path value { :keys [weight height] :as doc}]
( when ( and ( some #{id} [ :height :weight ]) weight height)
( assoc-in doc [ :bmi ] ( / weight ( * height height)))))] 이벤트 함수의 사용자 정의 맵을 bind-fields 로 제공하여 re-frame 과 같은 라이브러리와 함께 시약 형식을 사용합니다. 이 경우 시약 형식은 내부 상태를 보유하지 않으며 귀하가 제공 한 기능은 필드의 값을 얻고 저장 및 업데이트하는 데 사용됩니다. 예는 다음과 같습니다.
( ns foo.bar
( :require [re-frame.core :as re-frame]
[reagent-forms.core :refer [bind-fields]]))
; re-frame events
( re-frame/reg-event-db
:init
( fn [_ _]
{ :doc {}}))
( re-frame/reg-sub
:doc
( fn [db _]
( :doc db)))
( re-frame/reg-sub
:value
:<- [ :doc ]
( fn [doc [_ path]]
( get-in doc path)))
( re-frame/reg-event-db
:set-value
( fn [db [_ path value]]
( assoc-in db ( into [ :doc ] path) value)))
( re-frame/reg-event-db
:update-value
( fn [db [_ f path value]]
( update-in db ( into [ :doc ] path) f value)))
; Functions that will be called by each individual form field with an id and a value
( def events
{ :get ( fn [path] @( re-frame/subscribe [ :value path]))
:save! ( fn [path value] ( re-frame/dispatch [ :set-value path value]))
:update! ( fn [path save-fn value]
; save-fn should accept two arguments: old-value, new-value
( re-frame/dispatch [ :update-value save-fn path value]))
:doc ( fn [] @( re-frame/subscribe [ :doc ]))})
; bind-fields called with a form and a map of custom events
( defn foo
[]
[bind-fields
[ :div
[ :input { :field :text
:id :person.name.first
:valid? ( fn [doc]
( when ( = " Bob " ( -> doc :person :name :first ))
[ " error " ]))}]
[ :input { :field :text
:id :person.name.last }]]
events])요소 가시성은 진실한 값으로 취급 될 문서에서 ID를 제공하거나 기능을 설정하여 설정할 수 있습니다.
( re-frame/reg-event-db
:toggle-foo
( fn [db _]
( update-in db [ :doc :foo ] not)))
( re-frame/reg-sub
:bar-visible?
( fn [db _]
( :bar db)))
( re-frame/reg-event-db
:toggle-bar
( fn [db _]
( update db :bar not)))
( def form
[ :div
[ :input { :field :text
:id :foo-input
:visible? :foo }]
[ :input { :field :text
:id :bar-input
:visible? ( fn [doc] @( re-frame/subscribe [ :bar-visible? ]))}]
( defn page
[]
[ :div
[bind-fields
[ :input { :field :text
:id :foo-input
:visible? :foo-input-visible? }]
event-fns]
[ :button
{ :on-click #( re-frame/dispatch [ :toggle-foo ])}
" toggle foo " ]
[ :button
{ :on-click #( re-frame/dispatch [ :toggle-bar ])}
" toggle bar " ]])리 프레임을 사용하는 경우 리 프레임 이벤트를 사용하여 양식에서 필드의 재 계산을 트리거하는 것이 좋습니다. 예를 들어, 계산 된 BMI 필드를 살펴 보겠습니다.
( re-frame/reg-sub
:value
:<- [ :doc ]
( fn [doc [_ path]]
( get-in doc path)))
( defn bmi [{ :keys [weight height] :as doc}]
( assoc doc :bmi ( / weight ( * height height))))
( defmulti rule ( fn [_ path _] path))
( defmethod rule [ :height ] [doc path value]
( bmi doc))
( defmethod rule [ :weight ] [doc path value]
( bmi doc))
( defmethod rule :default [doc path value]
doc )
( re-frame/reg-event-db
:set-value
( fn [{ :keys [doc] :as db} [_ path value]]
( -> db
( assoc-in ( into [ :doc ] path) value)
( update :doc rule path value))))
( def events
{ :get ( fn [path] @( re-frame/subscribe [ :value path]))
:save! ( fn [path value] ( re-frame/dispatch [ :set-value path value]))
:doc ( fn [] @( re-frame/subscribe [ :doc ]))})
( defn row [label input]
[ :div
[ :div [ :label label]]
[ :div input]])
( def form-template
[ :div
[ :h3 " BMI Calculator " ]
( row " Height " [ :input { :field :numeric :id :height }])
( row " Weight " [ :input { :field :numeric :id :weight }])
( row " BMI " [ :label { :field :label :id :bmi }])])
( defn home-page []
[ :div
[ :h2 " BMI example " ]
[bind-fields form-template events]]) rule 다중 자료는 :set-value 이벤트가 호출되며 높이 또는 무게가 업데이트 될 때마다 BMI를 계산합니다.
reagent-forms.core/init-field Multimethod를 구현하여 사용자 정의 필드를 추가 할 수 있습니다. 메소드는 두 개의 매개 변수를 가져와야합니다. 여기서 첫 번째 매개 변수는 필드 구성 요소이고 두 번째 매개 변수는 옵션입니다.
기본적으로 옵션에는 get 과 save! 및 update! 열쇠. ID를 받아들이고 관련 문서 값을 반환하는 함수에 대한 핵심 사항을 get . 저장 save! 함수는 ID와 관련된 ID와 값을 허용합니다. update! 함수는 ID, 업데이트를 처리하는 함수 및 값을 허용합니다. 업데이트를 처리하는 기능은 이전 및 새 값을받습니다.
필드 값에 대한 사용자 정의 저장 형식을 만들기 위해 어댑터를 필드에 제공 할 수 있습니다. 이들은 키를 통해 필드로 전달되는 한 쌍의 함수입니다 :in-fn 및 :out-fn . :in-fn 저장된 항목을 수정하여 필드가 그것을 사용할 수 있도록 저장된 항목을 :out-fn 합니다. 예를 들어, 기본 js/Date 객체를 스토리지 형식으로 사용하려면 DatePicker를 초기화 할 수 있습니다.
[ :div { :field :datepicker :id :birthday :date-format " yyyy/mm/dd " :inline true
:in-fn #( when % { :year ( .getFullYear %) :month ( .getMonth %) :day ( .getDate %)})
:out-fn #( when % ( js/Date ( :year %) ( :month %) ( :day %)))}]어댑터는 널을 전달하여이를 처리 할 수 있어야합니다.
iOS의 Safari는 다음과 같은 300ms 지연이 발생합니다 :on-click 이벤트는 :touch-event 키를 사용하여 사용자 정의 트리거 이벤트를 설정할 수 있습니다. React에서 사용할 수있는 이벤트 목록은 여기를 참조하십시오. 예를 들어, 사용하려면 다음을 사용하려면 :on-click 이벤트를 트리거하려면 :on-touch-start 하여 다음을 수행 할 수 있습니다.
[ :input.form-control { :field :text :id :first-name :touch-event :on-touch-start }] 이벤트가 iOS에서 작동하기 위해 버튼 이외의 다른 요소에 대한 커서 스타일 cursor: pointer 를 설정해야합니다.
RECT 용 테이프 벤트 플러그 (TapeventPlugin)는 반응 형 이벤트를 생성하기위한 또 다른 옵션이며, 기능이 반응 자체에서 사용할 수있게 될 때까지.
이 프로젝트는 테스트를 실행하기 위해 Doo 사용합니다. DOO 지원 환경 중 하나를 설치해야합니다. 자세한 내용은 문서를 참조하십시오. 예를 들어 팬텀을 사용하는 것과 같은 테스트를 실행하려면 다음을 수행하십시오.
lein doo slimer test
Copyright © 2018 Dmitri Sotnikov
Eclipse Public License에 따라 버전 1.0 또는 이후 버전에서 배포됩니다.