Zend Framework - 在控制器中传递变量以进行ajax调用

时间:2022-03-23 21:33:27

Hi out there in Stackland! Here's my problem:

在Stackland,你好!这是我的问题:

I want to use my Zend controller to load an array from a database, and then pass it to javascript. I've decided the best way to do this is to use ajax to ask the controller for it's array, encode it in json, and then pass it down. However, I don't know how to pass the variable I loaded in my first action to the action that will pass it down when it gets called via ajax.

我想使用我的Zend控制器从数据库加载数组,然后将其传递给javascript。我已经决定最好的方法是使用ajax向控制器询问它的数组,用json编码,然后传递它。但是,我不知道如何将我在第一个操作中加载的变量传递给在通过ajax调用时将其传递下来的操作。

The original action which produces the view

产生视图的原始动作

public function indexAction()
    {
            $storeid = $this->getStoreId();

            if(!$storeid)
            {
                 $this->_forward('notfound');
                 return;
            }

            $store = $this->_helper->loadModel('stores');
            $store->getByPrimary($storeid);
    }

The action that will be called via ajax

将通过ajax调用的操作

public function getdataAction()
        {
            $this->_helper->Layout->disableLayout(); // Will not load the layout
            $this->_helper->viewRenderer->setNoRender(); //Will not render view

            $jsonResponse = json_encode($store);
            $this->getResponse()->setHeader('Content-Type', 'application/json')
                                ->setBody($jsonResponse);

        }

What I want is to pass $store in indexAction to getdataAction so it can send store as the jsonResponse. Note, these are called at two different times.

我想要的是将indexAction中的$ store传递给getdataAction,以便它可以将store作为jsonResponse发送。注意,这些是在两个不同的时间调用的。

Things I have tried that haven't worked:

我尝试过的事情没有奏效:

  1. setting $this->getRequest()->setParam('store', $store) in indexAction, and then using $this->getRequest()->getParam('store'), in getdataAction. I presume this hasn't worked because they're different http requests, so attaching a new param is useless.

    在indexAction中设置$ this-> getRequest() - > setParam('store',$ store),然后在getdataAction中使用$ this-> getRequest() - > getParam('store')。我认为这没有用,因为它们是不同的http请求,所以附加一个新的参数是没用的。

  2. using protected $_store in the controller itself, and then saving to it with indexAction, and using it in getdataAction. I'm not really sure why this isn't working.

    在控制器本身使用protected $ _store,然后使用indexAction保存到它,并在getdataAction中使用它。我不确定为什么这不起作用。

Is there a good way to pass a variable in this manner? Is there a way to pass a variable between different controllers?(I assume the answer to one is the answer to the other). Could I store it in a controller helper? Do I have to use a session, which I know would work but seems unnecessary? Is there a better way to pass variables to javascript? Am I asking too many questions? Any help would be outstanding. Thanks.

有一种以这种方式传递变量的好方法吗?有没有办法在不同的控制器之间传递一个变量?(我假设一个答案是另一个的答案)。我可以将它存储在控制器助手中吗?我是否必须使用会话,我知道这会有效,但似乎没必要?有没有更好的方法将变量传递给javascript?我问了太多问题吗?任何帮助都会很出色。谢谢。

5 个解决方案

#1


Maybe I'm reading the question wrong, but you should be able to just move $store into the constructor:

也许我正在读错的问题,但你应该能够将$ store移动到构造函数中:

public function __construct() {
    $store = $this->_helper->loadModel('stores');
    $store->getByPrimary($storeid);
}

and have it accessible in all *Action methods. Using sessions seems out of whack for this.

并且可以在所有* Action方法中访问它。使用会话似乎不是很糟糕。

#2


(disclaimer: I'm pretty new to ZF, so I'm interested in other answers found here, and have not tested the below!)

(免责声明:我对ZF很新,所以我对这里找到的其他答案感兴趣,并且没有测试下面的内容!)

In your view, where you put the ajax call, you will probably address it like:

在您的视图中,您放置ajax调用的位置,您可能会解决它:

(See ZF Documentation)

(参见ZF文档)

<?= $this->ajaxLink("Example 2",
                    "/YourController/getdata",
                    array('update' => '#content',
                          'class' => 'someLink'),
                    array('store' => $this->store)); ?>

Notice that in your indexAction, you store the store via:

请注意,在indexAction中,您可以通过以下方式存储商店:

 $this->view->store = $storeid;

Of course, you should note that a web-user could modify the store parameter as it is passed through via an URL.

当然,您应该注意,Web用户可以在通过URL传递时修改store参数。

#3


It would be better architecture to simply add a method to your IndexController, a helper, or somewhere, that returns an instance of Store. Use that method within your indexAction, and your getdataAction (would be more meaningful to call it ajaxAction). Also, you're forgetting to call sendResponse() (remember, you disabled autoRender):

简单地将一个方法添加到IndexController,一个帮助器或某个地方,返回一个Store实例将是更好的架构。在indexAction中使用该方法,并使用getdataAction(将其称为ajaxAction会更有意义)。此外,您忘记调用sendResponse()(记住,您禁用了autoRender):

    private function indexAction()
    {
        $this->getStore();
        //blah blah
    }

    private function getStore()
    {
        $storeid = $this->getStoreId();
        if(!$storeid)
        {
             $this->_forward('notfound');
             return;
        }
        $store = $this->_helper->loadModel('stores');
        $store->getByPrimary($storeid);
        return $store;
    } 

    public function ajaxAction()
    {
        $this->_helper->Layout->disableLayout(); // Will not load the layout
        $this->_helper->viewRenderer->setNoRender(); //Will not render view

        $jsonResponse = json_encode($this->getStore());
        $this->getResponse()->setHeader('Content-Type', 'application/json')
                            ->setBody($jsonResponse)
                            ->sendResponse();

    }

The manual says:

手册说:

To send the response output, including headers, use sendResponse().

要发送响应输出(包括标头),请使用sendResponse()。

http://framework.zend.com/manual/en/zend.controller.response.html

#4


All right, for those of you who want the answer to this too, I just sucked it up and used session. I put a Zend_Session->start() in the bootstrap. I then created a plugin to add a private variable $session to each controller. Then I set $this->session to Zend_Session_Namespace. To pass something, I pass it through session, so I use $this->session->store = $store. I can then pick it up elsewhere with $this->session->store. Thanks to those who tried to help!

好吧,对于那些想要得到答案的人,我只是把它吸了起来并使用了会话。我在引导程序中放了一个Zend_Session-> start()。然后我创建了一个插件,为每个控制器添加一个私有变量$ session。然后我将$ this-> session设置为Zend_Session_Namespace。为了传递一些东西,我将它传递给会话,所以我使用$ this-> session-> store = $ store。然后我可以使用$ this-> session-> store在其他地方选择它。感谢那些试图帮助的人!

#5


Just a quick addition to the comments. To output an array as JSON from within a controller, use:

只是对评论的快速补充。要从控制器中输出数组作为JSON,请使用:

$array = array('hi' => array('Hello' => 'World');
$this->_helper->json($array);

This sends the response and sets the specific headers for a JSON response

这将发送响应并设置JSON响应的特定标头

#1


Maybe I'm reading the question wrong, but you should be able to just move $store into the constructor:

也许我正在读错的问题,但你应该能够将$ store移动到构造函数中:

public function __construct() {
    $store = $this->_helper->loadModel('stores');
    $store->getByPrimary($storeid);
}

and have it accessible in all *Action methods. Using sessions seems out of whack for this.

并且可以在所有* Action方法中访问它。使用会话似乎不是很糟糕。

#2


(disclaimer: I'm pretty new to ZF, so I'm interested in other answers found here, and have not tested the below!)

(免责声明:我对ZF很新,所以我对这里找到的其他答案感兴趣,并且没有测试下面的内容!)

In your view, where you put the ajax call, you will probably address it like:

在您的视图中,您放置ajax调用的位置,您可能会解决它:

(See ZF Documentation)

(参见ZF文档)

<?= $this->ajaxLink("Example 2",
                    "/YourController/getdata",
                    array('update' => '#content',
                          'class' => 'someLink'),
                    array('store' => $this->store)); ?>

Notice that in your indexAction, you store the store via:

请注意,在indexAction中,您可以通过以下方式存储商店:

 $this->view->store = $storeid;

Of course, you should note that a web-user could modify the store parameter as it is passed through via an URL.

当然,您应该注意,Web用户可以在通过URL传递时修改store参数。

#3


It would be better architecture to simply add a method to your IndexController, a helper, or somewhere, that returns an instance of Store. Use that method within your indexAction, and your getdataAction (would be more meaningful to call it ajaxAction). Also, you're forgetting to call sendResponse() (remember, you disabled autoRender):

简单地将一个方法添加到IndexController,一个帮助器或某个地方,返回一个Store实例将是更好的架构。在indexAction中使用该方法,并使用getdataAction(将其称为ajaxAction会更有意义)。此外,您忘记调用sendResponse()(记住,您禁用了autoRender):

    private function indexAction()
    {
        $this->getStore();
        //blah blah
    }

    private function getStore()
    {
        $storeid = $this->getStoreId();
        if(!$storeid)
        {
             $this->_forward('notfound');
             return;
        }
        $store = $this->_helper->loadModel('stores');
        $store->getByPrimary($storeid);
        return $store;
    } 

    public function ajaxAction()
    {
        $this->_helper->Layout->disableLayout(); // Will not load the layout
        $this->_helper->viewRenderer->setNoRender(); //Will not render view

        $jsonResponse = json_encode($this->getStore());
        $this->getResponse()->setHeader('Content-Type', 'application/json')
                            ->setBody($jsonResponse)
                            ->sendResponse();

    }

The manual says:

手册说:

To send the response output, including headers, use sendResponse().

要发送响应输出(包括标头),请使用sendResponse()。

http://framework.zend.com/manual/en/zend.controller.response.html

#4


All right, for those of you who want the answer to this too, I just sucked it up and used session. I put a Zend_Session->start() in the bootstrap. I then created a plugin to add a private variable $session to each controller. Then I set $this->session to Zend_Session_Namespace. To pass something, I pass it through session, so I use $this->session->store = $store. I can then pick it up elsewhere with $this->session->store. Thanks to those who tried to help!

好吧,对于那些想要得到答案的人,我只是把它吸了起来并使用了会话。我在引导程序中放了一个Zend_Session-> start()。然后我创建了一个插件,为每个控制器添加一个私有变量$ session。然后我将$ this-> session设置为Zend_Session_Namespace。为了传递一些东西,我将它传递给会话,所以我使用$ this-> session-> store = $ store。然后我可以使用$ this-> session-> store在其他地方选择它。感谢那些试图帮助的人!

#5


Just a quick addition to the comments. To output an array as JSON from within a controller, use:

只是对评论的快速补充。要从控制器中输出数组作为JSON,请使用:

$array = array('hi' => array('Hello' => 'World');
$this->_helper->json($array);

This sends the response and sets the specific headers for a JSON response

这将发送响应并设置JSON响应的特定标头