• ZendFramework2学习笔记 json和ajax


        单程:

        View服务寄存器ViewJsonStrategy之后,有可能直接在控制器action是使用JsonViewModel输出json的数据。

        注冊ViewJsonStrategy:

    //module/Application/module.php
    
    class Module{
    
        public function onBootstrap(MvcEvent $e)
        {
            $eventManager        = $e->getApplication()->getEventManager();
         
            $eventManager->attach('render', array($this, 'registerJsonStrategy'), 100);
            
        }
    
        public function registerJsonStrategy(MvcEvent $e)
        {        
            $app          = $e->getTarget();
            $locator      = $app->getServiceManager();
            $view         = $locator->get('ZendViewView');
            $jsonStrategy = $locator->get('ViewJsonStrategy');
            $view->getEventManager()->attach($jsonStrategy, 100);        
        }
    }

        控制器的action中是使用JsonViewModel来输出json数据:

    //module/Test/src/Controller/TestController.php
    
    use ZendViewModelJsonModel;
    
    class TestController extends AbstractActionController
    {
        public function unitsAction() {
            $resultSet = $this->getUnitTable()->select();
            $units = array();
            foreach ($resultSet as $unit) {
                $units[$unit->idReal] = $unit->name;
            }
            return new JsonModel($units);
        }
    }
        通过这样的方式输出的json数据的Content-type类型是application/json,假设要改动Content-type类型为text/plain,则须要注冊一个晚于zf2的Rnder事件监听器的监听器来改动:
    //module/Application/module.php
    
    class Module{
    
        public function onBootstrap(MvcEvent $e)
        {
            $eventManager        = $e->getApplication()->getEventManager();
         
            $eventManager->attach('render', array($this, 'registerJsonStrategy'), 100);
    
    	attach(MvcEvent::EVENT_RENDER, function($event){
                    $event->getResponse()->getHeaders()->addHeaderLine('Content-Type', 'text/plain');
                }, -10000);
            
        }
    
        public function registerJsonStrategy(MvcEvent $e)
        {        
            $app          = $e->getTarget();
            $locator      = $app->getServiceManager();
            $view         = $locator->get('ZendViewView');
            $jsonStrategy = $locator->get('ViewJsonStrategy');
            $view->getEventManager()->attach($jsonStrategy, 100);        
        }
    }

        方式二:

        要实现zf2的控制器输出json数据,主要要解决2个问题。第一个就是改动header头的Content-type部分为

    

    'Content-Type: application/json'或者为'Content-Type: text/json',第二个就是输出json数据。

        改动header头,能够手动改动也能够自己主动改动。

        自己主动改动header头的方式是,使用zf2的JsonRenderer,或者json的view helper:

        1)使用JsonRenderer的方法:zf2默认使用PhpRender,因此须要在项目启动的时候,改动renderer。在启动模块(Application)的onBootStrap方法中,加入一个render事件的linstener(registerJsonStratery)。   

        public function onBootstrap($e)
        {
            // Register a render event
            $app = $e->getParam('application');
            $app->getEventManager()->attach('render', array($this, 'registerJsonStrategy'), 100);
        }
    

        在lisntener中将jsonStratery sttach到View的EventManger上。

        public function registerJsonStrategy($e)
        {
            $matches    = $e->getRouteMatch();
            $moduleRootName = $matches->getMatchedRouteName();//$moduleaRootName是在module.config.php中配置的route名称
            if ($moduleRootName != 'test') { //该模块全部控制器都设置为JsonRenderer
                return;
            }
    
            $app          = $e->getTarget();
            $locator      = $app->getServiceManager();
            $view         = $locator->get('ZendViewView');
            $jsonStrategy = $locator->get('ViewJsonStrategy');
    
            $view->getEventManager()->attach($jsonStrategy, 100);
        }

        2)使用view helper的方法:在控制器里面禁用layout($view->setTerminal(true);)或者在layout里面不要输出不论什么html,然后view里面json输出,

    $arr = array();
    $arr[] = 1111;
    $arr[] = 'aaaa';
    
    echo $this->json($arr);

        手动改动header头的方式,在view里面(禁用layout)或者在layout里面输出,

    header('Content-Type: application/json');

        zf2提供了json编解码类ZendJsonJson用于json数据编解码,该类会先尝试使用php函数json_encode和json_decode进行编解码,假设php不支持这2个函数。该类则会使用php脚本进行编解码,因此,在zf2中尽量使用该类而不要使用php的json_encode和json_decode进行编解码。
        样例1:让单个控制器的action输出json。

        方法一:

    //控制器代码
    
    use ZendJsonJson;
    
    //.......
    
    $arr = array();
    $arr[] = 1111;
    $arr[] = 'aaaa';
    $jsonData = Json::encode($arr); 
           
    $view =  new ViewModel(array(
        'jsonData' => $jsonData
    ));
    
    $view->setTerminal(true);
    
    return $view;
    
    //或者
    
    $arr = array();
    $arr[] = 1111;
    $arr[] = 'aaaa';
           
    $view =  new ViewModel(array(
        'arr' => $arr
    ));
    
    return $view;
    
    
    
    
    //视图代码
    
    header('Content-Type: application/json');
    
    echo $this->jsonData;
    
    //或者
    
    echo $this->json($this->arr);


        方法二:新建一个layout文件例如以下。

    //view/layout/json.phtml
    
    header('Content-Type: application/json');

        控制器代码,

    use ZendJsonJson;
    
    //.......
    
    $layout = $this->layout();
    $layout->setTemplate('layout/json');
    
    $arr = array();
    $arr[] = 1111;
    $arr[] = 'aaaa';
    $jsonData = Json::encode($arr); 
            
    $view =  new ViewModel(array(
        'jsonData' => $jsonData
    ));
    
    return $view;

        视图代码。

    echo $this->jsonData;

        样例2:让某个模块或者某个控制器都输出json,将renderer改为JsonRenderer而且更换默认的php layout后,就直接在view中输出json数据了。

        public function onRoute(MvcEvent $e)
        {
            $matches    = $e->getRouteMatch();
            $moduleRootName = $matches->getMatchedRouteName();//$moduleaRootName是在module.config.php中配置的route名称        
            if ($moduleRootName != 'test') { //该模块全部控制器都设置为JsonRenderer
                return;
            }
            $controllerName = $matches->getParam('controller');//$controllerName是在module.config.php中配置的controller名称
    	if ($controllerName != 'TestControllerTest') { //该控制器全部actions都设置为JsonRenderer
                return;
            }
            
            $e->getViewModel()->setTemplate("layout/json");  
        }
        
        public function onBootstrap(MvcEvent $e)
        {
            $eventManager        = $e->getApplication()->getEventManager();
            $moduleRouteListener = new ModuleRouteListener();
            $moduleRouteListener->attach($eventManager);
            
            $eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'onRoute'), -9000);
            $eventManager->attach('render', array($this, 'registerJsonStrategy'), 100);
        }
        
        public function registerJsonStrategy($e)
        {
            $matches    = $e->getRouteMatch();
            $moduleName = $matches->getMatchedRouteName();
    
            $matches    = $e->getRouteMatch();
            $moduleRootName = $matches->getMatchedRouteName();//$moduleaRootName是在module.config.php中配置的route名称        
            if ($moduleRootName != 'test') { //该模块全部控制器都设置为JsonRenderer
                return;
            }
            $controllerName = $matches->getParam('controller');//$controllerName是在module.config.php中配置的controller名称
    	if ($controllerName != 'TestControllerTest') { //该控制器全部actions都设置为JsonRenderer
                return;
            }
            
            $app          = $e->getTarget();
            $locator      = $app->getServiceManager();
            $view         = $locator->get('ZendViewView');
            $jsonStrategy = $locator->get('ViewJsonStrategy');
    
            $view->getEventManager()->attach($jsonStrategy, 100);        
        }

        之后,就能够直接在浏览器端的javascript中通过ajax获取json数据了:
    <script lang="javascript">
        $(document).ready(function(){
    
            $("#b01").click(function(){
    
                htmlobj=$.ajax({url:"/test/json",async:false});
    
                alert(htmlobj.responseText);
    
            });
    
        });    
    </script>


         样例3:直接在控制器中返回JsonModel

    use ZendViewModelJsonModel;
    
    
    class TestController extends AbstractActionController {
    
         public function uploadprogressAction()
        {
            $id = $this->params()->fromQuery('id', null);
            $progress = new SessionProgress();
            return new JsonModel($progress->getProgress($id));
        }
    
    }






    
    
    

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    App如何选择移动广告平台,开发者2
    mouseover与mouseenter与mousemove差额mouseout与mouseleave差额
    JFinal 的源代码超具体的分析DB+ActiveRecord
    Vim经常使用技巧总结1
    2015第4周四网摘
    Java任务调度
    2015第4周二网摘
    2015第4周一
    2015第三周日
    转SpringSided代码规范遵循
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4666607.html
Copyright © 2020-2023  润新知