2009-09-30 5 views
7

젠드 프레임 워크 MVC 구현을 사용하여 프로젝트를 시작하겠습니다.MVC : 어떻게 아약스?

아약스는 어떻게 작동합니까? 모든 아약스 코드를 컨트롤러에 두어야합니까? 또는보기로?

예를 들어 저자 인 'ivan'의 게시물을 페이지에 표시하고 싶습니다.

일반적으로 '/ posts/author/ivan'또는 smth와 같은 링크를 만들고 Posts 컨트롤러 (또는 Users 컨트롤러, 어디에서든지)에서 'byAuthorAction()'과 같은 새 Action을 만들고보기 (그리고 모델로부터의 게시물을 얻는 모든 코드가 거기에 간다.) 그리고 그것에 새로운 경로를 만든다.

json, xml 형식의 API, DRY 원칙을 지키고 코드 구조를 최대한 똑똑하게 디자인 할 수있는 기능을 추가하는 방법은 무엇입니까?

-

답변 해 주셔서 감사합니다! 내 상황과 같은 상황에서 MVC 디자인에 대한 의견을 보니 매우 기쁩니다. 기본 MVC 원칙에는 경험이 있지만 더 복잡한 경우에는 그렇지 않습니다. 어쩌면 유용한 링크일까요?

답변

13

당신은 정말 ContextSwitch 작업 도우미에 대한 설명서 장을 읽어야합니다. 그러나 여기에 대한 간략한 개요입니다 :

  • 보기 스크립트 (액션 name.phtml)

    은 어떤것 할 수 있도록 컨트롤러에서 일부 작업에 대한 컨텍스트 스위치를 초기화 할 수 있습니다 일반 HTML 출력
  • 에 사용되는 예를 들어 출력 XML - XML ​​컨텍스트는 기본적으로 지원되며 XML 컨텍스트에 대한 뷰 스크립트는 (action-name.xml.phtml)에 넣습니다. xml 컨텍스트는 또한 레이아웃 렌더링을 비활성화합니다.
  • json은 컨텍스트 스위치를 기본으로 지원되며 기본 옵션은 레이아웃과 뷰를 모두 비활성화하고 JSON 형식의 컨트롤러 동작에서 뷰에 할당 된 모든 변수를 출력하는 것입니다 이 옵션은 컨텍스트 스위치의 setAutoJsonSerialization (false) 메소드를 사용하여 토글 할 수 있습니다. 하지만 전환하면보기 스크립트 action-name.json을 만들어야합니다.phtml을 사용하고 JSON 형식의 변수를 직접 출력하십시오.

두 문맥 사이를 전환하려면 URL에 형식 매개 변수를 추가해야합니다./posts/author/ivan/format/json 또는/posts/author/ivan/format/xml. 형식을 지정하지 않으면 응용 프로그램에서 일반 html을 출력합니다.

컨텍스트 스위치의 특수 버전은 AjaxContext이며 수동으로이 스위치를 구성해야합니다. 'format'매개 변수를 사용하여 출력에 사용해야하는 형식을 식별하지는 않지만 요청에서 보낸 헤더를 검사하고 'X-Requested-With : XmlHttpRequest'헤더를 찾고 AjaxContext가 있는지 확인합니다. AjaxContext 액션 도우미를 사용하면 요청이 AJAX를 사용하여 실행될 경우 특정 액션에 사용할 컨텍스트를 지정할 수 있습니다.

8

ajax 요청을 감지하여 일반적인 작업과 구분할 수 있으므로 XML, JSON 등을 반환하기 위해 동일한 작업을 사용할 수 있습니다. 예를 들어 :

public function fooAction() 
{ 
    if($this->getRequest->isXmlHttpRequest()) { 
     echo json_encode($someData); 
    } else { 
     echo 'This is the normal output'; 
    } 
} 
+0

xml과 json 사이에서 선택하는 방법은 무엇입니까? html의/posts/author/ivan, /posts/author/ivan.xml, /posts/author/ivan.json, /posts/author/ivan.rss 등의 형식 URL을 사용해야합니까? –

+0

아니요, URL은 동일합니다. json_encode()를 사용하여 JSON 형식으로 내용을 출력 할 수 있습니다. http://ar2.php.net/json_encode –

+0

json은 가볍고 IMO로 작업하기가 쉽습니다. JSON 뷰를 만들거나 뷰를 사용하지 않고 데이터 배열을 json_encode()로 에코 할 수 있다면 자동 뷰 렌더링을 해제해야 할 것입니다. – karim79

2

보기는 HTML이 아닌 다른 수 있으며, 어느 파이프 라인은 아약스 포스트되는 요청에 반응 할 수 또는 컨트롤러가 반응 할 수 있습니다. 어느 쪽이든, 다른보기를 반환하는 것처럼 간단해야합니다.

1

AjaxContext Action-Helper (또는 확장 된 ContextSwitch 1)를 살펴보고 정확히 동일한 컨트롤러 코드를 사용하여 별도의보기 스크립트 (foo.json)로 전환 할 수 있습니다. phtml 또는 foo.ajax.phtml 등)을 자동으로 가져 오거나, 형식 매개 변수에서 자동으로 가져옵니다. 또는 JSON 액션 도우미를 사용하여 뷰에 할당 한 모든 변수를 포함하는 객체를 반환합니다. 당신의 컨트롤러에서 반향을 일으킬 필요가 있습니다.

+0

아, 물론. 나는 그것을 어떻게 보지 못했을 까? –

0

내 구문은 나이가있을 수 있습니다하지만 내 색인 컨트롤러에서 내 REST의 행동이 스케치는 :

/** 
* REST Action for this application. 
* 
* @return void 
*/ 
public function restAction() 
{ 
    $this->_helper->viewRenderer->setNoRender(true); 

    $parameters = (func_num_args() > 0) ? array($key => func_get_arg(0)) : $this->getRequest()->getParams(); 

    $key = 'restCommand'; 
    if(!array_key_exists($key, $parameters)) throw new Exception('Request for “' . $key . '” not found.'); 
    $restCommand = $parameters[$key]; 

    $xmlString = IndexModel::getEmptyXmlSet($restCommand); 
    $xslFile = IndexModel::getModelFilePath('index'); 

    //Handle OPML-driven REST commands: 
    if(stripos($restCommand, 'opml-') === 0) 
    { 
     $opmlCall = explode('-', $restCommand); 
     if(count($opmlCall) != 3) 
     { 
      $xmlString = Songhay_SimpleXml::getXmlMessage('OPML Call Not Recognized', array('The number of parameters are incorrect.')); 
     } 
     else 
     { 
      $opmlSet = $opmlCall[1]; 
      $opmlId = $opmlCall[2]; 
      $xmlString = IndexModel::getRssFragmentWithOpml($opmlSet, $opmlId); 
     } 
    } 

    //Handle general REST commands: 
    switch($restCommand) 
    { 
     case 'deeplink': 
      $key = 'id'; 
      if(!array_key_exists($key, $parameters)) throw new Exception('Request for “' . $key . '” not found.'); 
      $url = $parameters[$key]; 
      $xmlString = IndexModel::getRssFragment($url); 
      $xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile); 
      break; 
     case 'index': 
      $opmlFile = IndexModel::getModelFilePath('index', '.xml'); 
      $xmlString = Songhay_SimpleXml::loadXmlAndStripNamespaces($opmlFile); 
      $xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile); 
      break; 
     default: 
      $xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile); 
    } 

    $response = $this->getResponse(); 
    $response->setHeader('Content-Type', 'text/xml'); 
    $response->setBody($xmlString); 

    return; 
} 
0

내가 codeigniter와 함께 ajax를 사용하면 컨트롤러에서 바로 출력됩니다.

나는 또한 플래그, 즐겨 찾기 등과 같은 간단한 아약스 요청에 대해 별도의 컨트롤러를 사용합니다. 로그인, 연락처 등과 같은 아약스 요청의 경우 논리를 일반적인 경로 (예 : domain.com/contact)에 추가하면 아약스 요청. 그런 다음 json을 출력하고 스크립트 실행을 중단합니다.