1.Visualforce는 Lightning Platform에서 호스팅할 수 있는 모바일 및 데스크탑 앱을 위한

정교한 사용자 정의 사용자 인터페이스를 구축할 수 있게 해주는 웹 개발 프레임워크다.

 

또한 Salesforce의 기본 제공 기능을 확장하고 새로운 기능으로 교체하면서완전히 새로운 앱을

구축할 수 있다고는 하는데 기존 어플을 만든 경험은 없기 때문에 그냥 개발하는 툴이라는 생각밖에 들지 않는다.

 

apex라는 자체 언어를 여기에도 끼얹어서 그런지

이유는 모르겠지만 코드 앞부분에 apex:를 붙이는 것을 좋아한다.

//정보 수정 페이지에 어울리는 기능
<apex:page standardController="Contact" >
    <apex:form >
        <apex:pageBlock title="Edit Contact">
            <apex:pageBlockSection columns="1">
                <apex:inputField value="{!Contact.FirstName}"/>
	                <apex:inputField value="{!Contact.LastName}"/>
                <apex:inputField value="{!Contact.Email}"/>
                <apex:inputField value="{!Contact.Birthdate}"/>
            </apex:pageBlockSection>
            <apex:pageBlockButtons >
                <apex:commandButton action="{!save}" value="Save"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
</apex:page>

 

 

2.아래에는 부분적으로 사용되는 사용 예시 정리다.

//이미지 첨부
<apex:image url="https://developer.salesforce.com/files/salesforce-developer-network-logo.png"/>

//글로벌 값 조회
//Visualforce 표현식은 대소문자를 구분하지 않으며, {! ... } 내 공백은 무시
{! $GlobalName.fieldName }

//내부 계산 가능
<p>The year today is {! YEAR(TODAY()) }</p>
<p>Tomorrow will be day number  {! DAY(TODAY() + 1) }</p>
<p>Let s find a maximum: {! MAX(1,2,3,4,5,6,5,4,3,2,1) } </p>
<p>The square root of 49 is {! SQRT(49) }</p>
<p>Is it true?  {! CONTAINS('salesforce.com', 'force.com') }</p>
<p>{! IF( CONTAINS('salesforce.com','force.com'),'Yep', 'Nope') }</p>

//글로벌 값 수식 표현
({! IF($User.isActive, $User.Username, 'inactive') })

//점 표기법으로 레코드간의 관계 탐색 가능
Account owner: {! Account.Owner.Name }


//standardController 설정으로 인한 접근 가능
<apex:page standardController="Contact">
    {! Contact.lastName}
    {! Contact.FirstName}
    {! Contact.Owner.Email}
</apex:page>


//standardController 내부 value, var 사용
<apex:page standardController="Account">
    <apex:pageBlock title="Account Details">
        <apex:pageBlockSection >
            <apex:outputField value="{! Account.Name }"/>
            <apex:outputField value="{! Account.Phone }"/>
            <apex:outputField value="{! Account.Industry }"/>
            <apex:outputField value="{! Account.AnnualRevenue }"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
       <apex:pageBlockTable value="{!Account.contacts}" var="contact">
          <apex:column value="{!contact.Name}"/>
          <apex:column value="{!contact.Title}"/>
          <apex:column value="{!contact.Phone}"/>
       </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>


//페이지네이션 및 필터
<apex:page standardController="Contact" recordSetVar="contacts">
    <apex:form >
        <apex:pageBlock title="Contacts List" id="contacts_list">
            Filter:
            <apex:selectList value="{! filterId }" size="1">
                <apex:selectOptions value="{! listViewOptions }"/>
                <apex:actionSupport event="onchange" reRender="contacts_list"/>
            </apex:selectList>
            <!-- Contacts List -->
            <apex:pageBlockTable value="{! contacts }" var="ct">
                <apex:column value="{! ct.FirstName }"/>
                <apex:column value="{! ct.LastName }"/>
                <apex:column value="{! ct.Email }"/>
                <apex:column value="{! ct.Account.Name }"/>
            </apex:pageBlockTable>
            <!-- Pagination -->
            <table style="width: 100%"><tr>
                <td>
                    Page: <apex:outputText value=" {!PageNumber} of {! CEILING(ResultSize / PageSize) }"/>
                </td>
                <td align="center">
                    <!-- Previous page -->
                    <!-- active -->
                    <apex:commandLink action="{! Previous }" value="« Previous"
                         rendered="{! HasPrevious }"/>
                    <!-- inactive (no earlier pages) -->
                    <apex:outputText style="color: #ccc;" value="« Previous"
                         rendered="{! NOT(HasPrevious) }"/>
                    &nbsp;&nbsp;
                    <!-- Next page -->
                    <!-- active -->
                    <apex:commandLink action="{! Next }" value="Next »"
                         rendered="{! HasNext }"/>
                    <!-- inactive (no more pages) -->
                    <apex:outputText style="color: #ccc;" value="Next »"
                         rendered="{! NOT(HasNext) }"/>
                </td>
                <td align="right">
                    Records per page:
                    <apex:selectList value="{! PageSize }" size="1">
                        <apex:selectOption itemValue="1" itemLabel="1"/>
                        <apex:selectOption itemValue="5" itemLabel="5"/>
                        <apex:selectOption itemValue="10" itemLabel="10"/>
                        <apex:selectOption itemValue="20" itemLabel="20"/>
                        <apex:actionSupport event="onchange" reRender="contacts_list"/>
                    </apex:selectList>
                </td>
            </tr></table>
        </apex:pageBlock>
    </apex:form>
</apex:page>


//링크걸기
<apex:page standardController="Account" recordSetVar="accounts">
        <apex:repeat value="{! Accounts }" var="a">
            <li>
                <apex:outputLink value="/{! a.ID }">
                    {! a.name}    
                </apex:outputLink>  
            </li>
        </apex:repeat>
</apex:page>


//정적 주소에서 이미지 가져오기 vfimagetest = 압축파일명 
<apex:page >
    <apex:image url="{!URLFOR($Resource.vfimagetest, 'cats/kitten1.jpg')}" />
</apex:page>


//이름 필터링 controller
public class ContactsListWithController {
    private String sortOrder = 'LastName';
    public List<Contact> getContacts() {
        List<Contact> results = Database.query(
            'SELECT Id, FirstName, LastName, Title, Email ' +
            'FROM Contact ' +
            'ORDER BY ' + sortOrder + ' ASC ' +
            'LIMIT 10'
        );
        return results;
    }
    public void sortByLastName() {
        this.sortOrder = 'LastName';
    }
    public void sortByFirstName() {
        this.sortOrder = 'FirstName';
    }
}


//custom controller 사용
<apex:page controller="ContactsListWithController">
    <apex:form>
        <apex:pageBlock title="Contacts List" id="contacts_list">
            <apex:pageBlockTable value="{! contacts }" var="ct">
                <apex:column value="{! ct.FirstName }">
                    <apex:facet name="header">
                        <apex:commandLink action="{! sortByFirstName }"
                            reRender="contacts_list">First Name
                        </apex:commandLink>
                    </apex:facet>
                </apex:column>
                <apex:column value="{! ct.LastName }">
                    <apex:facet name="header">
                        <apex:commandLink action="{! sortByLastName }"
                            reRender="contacts_list">Last Name
                        </apex:commandLink>
                    </apex:facet>
                </apex:column>
                <apex:column value="{! ct.Title }"/>
                <apex:column value="{! ct.Email }"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>


//직접 작성한 콘트롤러 실패 후 정답
public class NewCaseListController {
//    public Static List<Case> getNewCases () {
  //      List<Case> returnData = new List<Case>();
    //    List<Case> results = Database.query(
     //       'SELECT Id, CaseNumber, status '+
      //      'FROM Case' 
 //       );
   //     for(Case a : results){
     //       if(a.Status == 'New'){
       //         returnData.add(a);
         //   }
   //     }
     //   return returnData;
   // }

    list<case> newcase = new list<case>();
        public list<case> GetNewCases() 
        {
        newcase = [Select Id,CaseNumber from case where status='New'];
    
            return newcase;
        }
}

// 콘트롤러 사용
<apex:page controller="NewCaseListController">
        <apex:repeat value="{! newCases }" var="case">
            <li>
                <apex:outputLink value="/{! case.ID }">
                    {! case.ID}    
                </apex:outputLink>  
                    {! case.CaseNumber}    
            </li>
        </apex:repeat>
</apex:page>

 

 

3.위에서 언급한 전역변수는 26가지가 있다.

$Action

$Api

$Asset

$Cache.Org

$Cache.Session

$Component

$ComponentLabel

$CurrentPage

$FieldSet

$Label

$Label.Site

$MessageChannel

$Network

$ObjectType

$Organization

$Page

$Permission

$Profile

$Resource

$SControl

$Setup

$Site

$System.OriginDateTime

$User

$User.UITheme and

$User.UIThemeDisplayed

$UserRole

 

 

4.Visualforce 표현식은 대소문자를 구분하지 않으며, {! ... } 내 공백은 무시되고 &로 문자열 수식을 합칠 수 있다.

({! $User.FirstName & ' ' & $User.LastName })

 

 

5.SaaS, PaaS, IaaS등 여러가지 종류가 존재하는데

뒤의 aaS 부분은 as a Service의 약자로 동일하며

앞부분만 Software, Platform, Infrastructure이라는 차이가 있다.

 

이름에서도 알 수 있듯 SaaS는 소프트웨어까지 적용되 있기 때문에

사용만 하면 되는 서비스를 말하고

PaaS는 온프레미스나 클라우드의 최신 애플리케이션 등을 구축하고 관리하는 데 사용되는

클라우드 서비스 세트라고 볼 수 있다.

 

여기서 온프레미스는 직접 컴퓨터를 하나하나 연결해서 서버를 만드는 작업을 통해

모든 과정을 사용자가 통제할 수 있는 환경을 말하는데

이런 환경을 구축했기 때문에 AWS가 IaaS를 제공할 수 있기도 하다.

 

 

6.Heroku에서는 RESTful API 구축, 고객과 소통할 수 있는 웹 사이트 구축,

API 서비스를 통해 모바일 및 IoT 강화, 플랫폼의 기능을 완성하는 보완 도구를 제공,

빠르게 새로운 아이디어를 시도해 보고 나면 응용 프로그램을 삭제 가능 등

여러가지 장점들을 가지고 있다.

 

 

7.Heroku는 Git, GitHub, Heroku 검토 앱, 배포 버튼, Docker, Hashicorp Terraform 등으로

배포를 할 수 있으며 각각의 장점들은 아래의 표에서 확인할 수 있다.

Deployment Method Requirements Best Suited For Pros Cons
Git - Full access to both the Git repository and Heroku app to manually push code to production. - Projects with small, trusted teams. - Simple to add to any Git-based workflow - Supports Git submodules  - Can track your source code in Subversion or another revision control system - Requires manually deploying code with git push
GitHub Integration - Admin access to a GitHub repo - Automated deployments - Automatically deploys apps and keeps them up to date - Integrates with Heroku Pipelines, Review Apps, and Heroku CI for a continuous workflow - No support for Git submodules
Heroku Review Apps - The GitHub integration  - Heroku Pipelines - Projects in GitHub with apps deployed to multiple environments. - Option to automatically create and update Review Apps for each PR - Supports Docker images - Supports Heroku Private Spaces for testing changes in an isolated environment - Additional costs from resources used in Review Apps. See tips on optimizing costs on the Dev Center.
'Deploy to Heroku' Button - A GitHub repo - A valid app.json file in the project's root directory - Apps provided to your users or customers, such as open-source projects - Onboarding new hires - Deploy with clicks - Easy to add to a project's README file or web page - Provides a template with pre-configured default values, environment variables, and parameters - No support for Git submodules - No auto-updates when the repo changes. You must use another deployment method for subsequent deploys to the same app.
Docker - A Docker image - Apps with custom stacks. - More control over your app's stack - Automatically generate images, or push an existing image to the container registry - Consistency between environments - Compatible with Heroku Review Apps - You must maintain your own stack - No support for pipeline promotions
Hashicorp Terraform - Terraform - Apps with complex infrastructure components - Automates Heroku app deployments - Allows you to deploy Heroku apps as code - Simplifies the management of large, complex deployments - Can configure apps, Private Spaces, or resources from other providers into a repeatable multi-provider architecture Heroku Support can't provide help with these more complex deployments

 

8.Heroku의 코드는 Dynos라는 내부 플랫폼에서 실행되며

공룡과 관련이 있을 것 같은 이름이지만 단지 Linux 운영 체제 기반 런타임 컨테이너일 뿐이다.

 

런타임 컨테이너는 둘 이상의 Dynos를 구별해 서로 충돌없이 격리된 환경에서 동작할 수 있게 한다.

 

슬러그는 배포하기 위해 최적화된 응용 프로그램의 압축 및 사전 패키징된 복사본이며

Heroku에 푸시할 경우 슬러그 컴파일러가 코드를 수신하고

빌드팩을 이용해 구현 및 컴파일하게 된다.

 

 

 

 

 

(1).백준 1212번 8진수 2진수는 입력된 어마어마어마하게 큰(숫자일 수 있는) 8진수 숫자를 받아

2진수 숫자로 변경해야 하는 문제였다.

 

toString으로 2진수 변경을 쉽게 할 수 있었지만

BigInt로 처리해야하는 규모의 8진수 숫자를 8진수로 인식하게 만드는 것이 문제였는데

예전에 배웠던 0O, 0X등의 8, 16진수 규칙을 떠올리며 간단하게 해결할 수 있었다.

const input = '0O' + `314`
console.log(BigInt(input).toString(2))

'회고' 카테고리의 다른 글

[수습일지] - 20(주말)  (0) 2023.04.15
[수습일지] - 19  (0) 2023.04.14
[수습일지] - 17  (0) 2023.04.12
[수습일지] - 16  (0) 2023.04.11
[수습일지] - 15  (0) 2023.04.10

+ Recent posts