【问题标题】:CakePHP AutoComplete QuestionCakePHP 自动完成问题
【发布时间】:2010-09-19 10:39:55
【问题描述】:

我正在开发书评应用程序,并且在创建书评时使用自动完成功能来搜索书名。评论模型有一个关联的 book_id 字段,并且关系设置为评论 hasOne book 和 book hasMany reviews。

我正在尝试传递 Book.id(到 book_id 字段),但我想显示 Book.name 供用户选择。使用默认设置(通过 CakePHP 的教程完成),我只能传递 Book.name。是否可以显示名称并传递id?

另外,我通过审查控制器的 create() 操作中的以下代码传递它:

$this->data['Review']['book_id'] = $this->data['Book']['id'];

这是在 CakePHP 中正确的做法吗?我知道在 Ruby on Rails 中它是自动的,但我似乎无法让它在 CakePHP 中自动运行。最后,我没有使用生成器,因为它在我的共享托管环境中不可用......所以如果这是错误的方式,除了我的模型中的关联之外,我还需要什么来使其自动发生?

感谢您的帮助,我保证这是我一段时间内的问题......

更新- 我尝试了以下方法,但它不起作用。任何想法为什么?

    function autoComplete() {
    $this->set('books', $this->Book->find('all', array(
        'conditions' => array(
            'Book.name LIKE' => $this->data['Book']['name'].'%'
        ),
        'fields' => array('id','name')
    )));
    $this->layout = 'ajax';
}

问题是,当我在控制器中使用上面的代码时,表单提交了,但是并没有保存记录……也没有抛出任何错误,这很奇怪。

更新2:

我已经确定这不起作用的原因是数组类型不同,您无法使用 autoComplete 帮助程序更改数组类型。作为一种解决方法,我尝试了以下操作,但它不起作用。任何人都可以提供指导吗?

function create() {
    if($this->Review->create($this->data) && $this->Review->validates()) {
        $this->data['Review']['user_id'] = $this->Session->read('Auth.User.id');
        $this->Book->find('first', array('fields' => array('Book.id'), 'conditions' => array('Book.name' => $this->data['Book']['name'])));
        $this->data['Review']['book_id'] = $this->Book->id;
        $this->Review->save($this->data);
        $this->redirect(array('action' => 'index'));
    } else {
        $errors = $this->Review->invalidFields();
    }
}

最终更新:

好的,我发现帮助程序只接受 find(all) 类型或数组,并且“id”字段没有通过,因为它只应用于正在生成的自动完成的 LI 列表。因此,我使用observeField 来获取信息,然后进行数据库查找,并尝试使用ID 动态创建一个隐藏字段,但这不起作用。最后,由于明显的 Scriptaculous 限制,observeField 只会采用我输入的字符而不是我单击的字符。所以,我现在最终选择了一个下拉框解决方案,最终可能会研究其他东西。无论如何感谢所有的帮助!

【问题讨论】:

    标签: cakephp


    【解决方案1】:

    首先,$this->data 将仅包含 ['Book']['id'] 如果该字段存在于表单中(即使它被隐藏)。

    要通过name 选择某些内容并返回id,请使用 find 方法的列表变体,即:

        $selectList = $this->Book->find('list', array(
                                                   'fields' => array(
                                                                  'id', 
                                                                  'name'
                                                )));
        $this->set('selectList', $selectList);
    

    在视图中,您现在可以将$selectList 用于选择元素中的选项:

        echo $form->input('Book.id', array('type' => 'hidden'));
        echo $form->input('template_id', array(
                                            'options' => $selectList,
                                            'type' => 'select'
                                         ));
    

    【讨论】:

    • 我刚刚在上面发布了一个问题。不知道为什么两个字段都没有通过?那里的语法正确吗?如果是这样,我可以检查其他内容,但我没有在控制器中看到任何拼写错误或任何内容。
    • 您使用的是 find('all'...) 而不是 find('list'...)。我不知道您的应用程序的逻辑,但尝试在保存语句之前使用 debug($this->data) 语句来查看表单返回的内容。
    • 我只是将 AjaxHelper 用于自动完成,作为 CakePHP 中的标准。当我切换到“列表”而不是“全部”时,它在 ajax 下拉列表中显示“不能使用字符串偏移作为数组”。这可能与它使用 LIKE 查询有关?
    • 调试告诉你什么?您还可以使用 Firefox 中的 Firebug 插件来查看当您选择一本书时设置了什么。
    • 这让我相信这是因为 helper 以特定方式处理数据,并且“list”和“all”find() 的数组格式不同。下拉菜单的错误是“Cannot Use String Offset as an Array”,你知道那个错误是什么意思吗?
    猜你喜欢
    • 2010-11-09
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2011-07-18
    • 2013-02-13
    • 2010-12-04
    • 2011-08-08
    相关资源
    最近更新 更多