기본 콘텐츠로 건너뛰기

vulcanJS - 10. Posts Update/Delete

마지막으로 수정과 삭제를 구현해보면 목록 조회(List), 상세 조회, 쓰기, 수정, 삭제까지 모든 필요한 요소를 아우를 수 있을 것이다.
감이 좋은 분들은 눈치 챘을지도 모르겠지만 사실 수정이란 건 UI면에서 볼때 이미 양식이 채워져있는 신규 쓰기와 별반 다르지 않다.

먼저 해야할 것은 역시나 Component를 만드는 일이다.
$ vulcan g component
? Package name spectrum-simplebb
? Component name PostsEditComponent
? Component type Class Component
? Register component Yes
   create packages/spectrum-simplebb/lib/components/PostsEditComponent.jsx
 conflict packages/spectrum-simplebb/lib/components/index.js
? Overwrite packages/spectrum-simplebb/lib/components/index.js? overwrite
    force packages/spectrum-simplebb/lib/components/index.js
PostsEditComponent를 만들었다.
route도 만들자. /posts/edit/:id 이렇게 경로를 만들면 좋겠다. 그러고보니 이전 글에서 만든 상세보기도 /posts/view/:id 형식으로 만들껄 그랬다.
$ vulcan g route
? Package name spectrum-simplebb
? Route name postsEdit
? Route path /posts/edit/:_id
? Component name PostsEditComponent
? Layout name
 conflict packages/spectrum-simplebb/lib/modules/routes.js
? Overwrite packages/spectrum-simplebb/lib/modules/routes.js? overwrite
    force packages/spectrum-simplebb/lib/modules/routes.js
Route도 만들었다.

그렇다면 다음은 /posts/edit/:_id로 들어올 진입점을 만들자. PostsSingleComponent가 괜찮아보인다.
<Link to={`/posts/edit/${this.props.documentId}`}>Edit</Link>
이 부분을 삽입하여주자.
import React, { Component } from 'react';
import { Link } from 'react-router';
import { registerComponent, withDocument } from 'meteor/vulcan:core';
import Posts from "../modules/posts/collection.js";
class PostsSingleComponent extends Component {
  render () {
    return (
      this.props.loading &&
        <div />
      ||
        <div>
          <h1>{this.props.document.title}</h1>
          <pre>
            {this.props.document.body}
          </pre>
          <div>
            <Link to={`/posts/edit/${this.props.documentId}`}>Edit</Link>
          </div>
          <div>
            <Link to='/'>to Home</Link>
          </div>
        </div>
    );
  }
}
registerComponent('PostsSingleComponent', PostsSingleComponent, [withDocument, {
  collection: Posts
}]);
export default PostsSingleComponent;
상위 Component인 PostsViewComponent가 _id를 documentId로 전달하므로 같은 걸 사용했다.
목록>상세>수정까지 진입하는 길은 다 만들어졌다.
수정 서식을 보여주도록 PostsEditComponent를 고쳐보자.

사실 PostsEditComponent는 PostsNewComponent와 거의 같다.
단 하나 차이점이 있다면 SmartForm에 documentId를 지정하는 것만이 다르다.
즉, SmartForm Component는 documentId를 지정할 경우 수정을 하고 없을 경우 새로운 Document를 생성한다고 보면된다.
import React, { Component } from 'react';
import { registerComponent, Components } from 'meteor/vulcan:core';
import Posts from  "../modules/posts/collection.js";
class PostsEditComponent extends Component {
  render () {
    return (
      <div>
        <Components.SmartForm
          collection={Posts}
          documentId={this.props.params._id}
        />
      </div>
    );
  }
}
registerComponent('PostsEditComponent', PostsEditComponent);
export default PostsEditComponent;
날로 먹는다고 봐야 한다.
아직 날로 먹는 건 끝이 아니다.
SmartForm은 collection과 documentId 말고도 몇 가지가 더 있기 때문이다.

지금 현재 구현은 수정이라는 기능엔 충실하지만 실제로 사용자는 수정을 완료한 뒤에 멀뚱하게 그자리에 있는 것을 원하지 않을 것이다.
successCallback을 추가하여 수정 완료 시 상세 조회 화면으로 돌아가도록 해 보자.
import React, { Component } from 'react';
import { registerComponent, Components } from 'meteor/vulcan:core';
import Posts from  "../modules/posts/collection.js";
class PostsEditComponent extends Component {
  render () {
    return (
      <div>
        <Components.SmartForm
          collection={Posts}
          documentId={this.props.params._id}
          successCallback={
            ()=> this.props.router.push(`/posts/${this.props.params._id}`)
          }
        />
      </div>
    );
  }
}
registerComponent('PostsEditComponent', PostsEditComponent);
export default PostsEditComponent;
router객체 안에 있는 push를 사용하여 해당 글로 다시 돌아가보았다.
신규 작성에 비해 수정을 위해서 우리가 해준 건 딱 두개 밖에 없다.
  1. documentID 를 추가했고
  2. 수정 후 callback을 구현했다.
그러면 이젠 마지막 관문인 삭제 구현을 해야하는데 이게 의외로 싱겁다.
SmartForm에 속성 두개만 추가하면 된다.
  1. showRemove={true} 를 추가하여 삭제 기능을 화면에 보여주고
  2. removeSuccessCallback을 구현하여 삭제 후 callback을 구현하면 된다.
한번 해보자.
먼저 removeSuccessCallback 후엔 이미 자신이 사라진 이후니까 successCallback처럼 자신의 글로 되돌아 갈 수 없다.
목록으로 가도록 해주자.
          removeSuccessCallback ={
            ()=> this.props.router.push(`/`)
          }
이 정도가 적당할 것 같다.
전부 모아보자.
import React, { Component } from 'react';
import { registerComponent, Components } from 'meteor/vulcan:core';
import Posts from  "../modules/posts/collection.js";
class PostsEditComponent extends Component {
  render () {
    return (
      <div>
        <Components.SmartForm
          collection={Posts}
          documentId={this.props.params._id}
          successCallback={
            ()=> this.props.router.push(`/posts/${this.props.params._id}`)
          }
          showRemove={true}
          removeSuccessCallback ={
            ()=> this.props.router.push(`/`)
          }
        />
      </div>
    );
  }
}
registerComponent('PostsEditComponent', PostsEditComponent);
export default PostsEditComponent;
showRemove와 removeSuccessCallback을 구현하였다.


Delete 기능이 아래 달라붙었다.
버튼 같지 않지만 그거야 스타일링 하면 되고 클릭해보자.
확인 alert이 뜨고.
홈으로 이동 후 삭제가 잘 이루어졌다.
갑자기 수정/삭제가 너무 허망하게 구현이 된 것 같은 느낌은 있지만 여기까지 필요한 최소한의 기능은 모두 구현해보았다고 할 수 있다.

이제 나머지는 디테일을 위한 공부!


Vulcan 메뉴얼은 당연히 읽고

Meteor 도 봐두고

GraphQL도 익히고

React도 보고

즐거운 공부 뿐이다. 즐기자.

이 블로그의 인기 게시물

React-Native App 개발 시 Expo 선택 전에 고려해야할 것.

Expo는 지옥같은 React-Native 개발 환경 아래 섬광처럼 빛나는 훌륭한 도구지만 빛이 있으면 어둠이 있는 법.
https://docs.expo.io/versions/latest/introduction/why-not-expo.html 에선 이런 경우에 Expo를 사용을 고려하라고 전하고 있다.


독립형 앱에 이미지 같은 정적 자원(Assets)들을 함께 묶어 배포할 수 없다.background 혹은 장치가 잠자기 모드일때 코드 실행을 지원하지 않는다.일부 API를 미지원. Bluetooth, WebRTC 같은 건 아직.오버헤드가 꽤 크다. iOS 25MB, Android 20MBPush Notification의 경우 OneSignal 같은 외부서비스를 활용하려면 ExpoKit을 사용하거나 Expo가 아닌 React-Native를 사용해야한다.Staging/Production같은 다양한 디플로이 환경. 하지만 이 경우 https://github.com/oliverbenns/expo-deploy 같은 선택지도 있으니 참조할 것

ESP32 DevBoard 개봉기

오늘 드디어 손에 넣었다. ESP32 DevBoard!
Adafruit 에서 15개 한정 재입고 트윗을 보고 광속 결제.
그리고 1주일의 기다림. 사랑해요 USPS <3
알리를 이용하다보니 1주일 정도는 광속 배송임.
물론 배송비도 무자비함 -_ㅜ
15개 한정판 adafruit 발 dev board
그놈이 틀림없으렸다.
오오 강려크한 포스
ESP32_Core_board_V2라고 적혀있군요.
ESP32 맞구요. 네네. ESP32-D0WDQ6 라고 써있는데 D → Dual-core 0 → No internal flash W → Wi-Fi D → Dual-mode Bluetooth Q → Quad Flat No-leads (QFN) package 6 → 6 mm × 6 mm package body size 라고 함.
길이는 이정도
모듈크기는 이정도
코어는 6mm밖에 안해! 여기에 전기만 넣으면 BLE+WIFI!
밑에 크고 발 8개 달린 놈은 FM25Q32라고 32Mbit 플래시메모리
ESP8266 DevBoard 동생이랑 비교 크고 아름다운 레귤레이터랑 CP2102 USB Driver가 붙어있음.
ESP8266 DevBoard엔 CH340G 인데 확 작아졌네.
머리를 맞대어 보았음.
모듈크기는 아주 약간 ESP32가 더 큰데 워낙에 핀이 많고 촘촘함. ESP8266인 ESP12는 핀 간격이 2.00mm인데 비해
ESP32는 1.27mm 밖에 안함.
딱봐도 비교가 될 정도.
https://www.sparkfun.com/news/2017 크고 아름다운 Pinouts

ESP8266 보드랑 별로 안달라보인다.
http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx#mac
에서 CP2102 드라이버를 설치하고
screen 으로 연결해보자.
내 경우엔 tty.SLAB_USBtoUART 로 잡혔다.
어디서 기본 속도가 115200bps 라고 들은 적이 있어서
screen /dev/tty.SLAB_USBtoUART …

MQTT Broker Mosquitto 설치 후 설정

우분투 기준
$ sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
$ sudo apt-get update
하고

$ sudo apt-get install mosquitto
으로 설치하면 서비스까지 착실하게 올라간다.

설치는 간단한데 사용자를 만들어야한다.

/etc/mosquitto/mosquitto.conf 파일에서 권한 설정을 변경하자.
allow_anonymous false
를 추가해서 아무나 못들어오게 하자.
$ service mosquitto restart
서비스를 재시작.
이제 사용자를 추가하자. mosquitto_passwd <암호파일 경로명> <사용자명> 하면 쉽게 만들 수 있다.
# mosquitto_passwd /etc/mosquitto/passwd admin Password:  Reenter password: 
암호 넣어준다. 두번 넣어준다.
이제 MQTT 약을 열심히 팔아서 Broker 사글세방 임대업을 하자.