Yii2:通过Widget重用表单字段

时间:2017-08-13 21:34:45

标签: ajax yii2 widget jquery-select2

我有一个字段是一个Select2小部件字段,它通常用于多种形式,但复制粘贴相同的代码一段时间后真的很烦人。因此,我决定最好只为这个领域创建一个小部件。

该字段如下

extern crate hyper;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use hyper::header::{Authorization, Header, Raw, Scheme};
use serde::{Deserialize, Deserializer};

#[derive(Debug, Deserialize, PartialEq)]
struct Headers<S>
where
    S: Scheme + 'static,
{
    #[serde(deserialize_with = "auth_header", default = "no_auth")]
    authorization: Option<Authorization<S>>,
    #[serde(rename = ":path")]
    path: String,
}

fn auth_header<'de, D, S>(deserializer: D) -> Result<Option<Authorization<S>>, D::Error>
where
    D: Deserializer<'de>,
    S: Scheme + 'static,
{
    let s = String::deserialize(deserializer)?;
    let auth = Authorization::parse_header(&Raw::from(s.into_bytes()));
    auth.map(|a| Some(a)).map_err(serde::de::Error::custom)
}

fn no_auth<S>() -> Option<Authorization<S>>
where
    S: Scheme + 'static,
{
    None
}

#[cfg(test)]
mod test {
    use hyper::header::{Basic, Bearer};
    use serde_json;
    use super::*;

    #[test]
    fn de_json_basic() {
        let data = r#"{
                        "authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
                        ":path": "/service/",
                        ":method": "GET"
                      }"#;

        let message = Headers {
            authorization: Some(Authorization(Basic {
                username: "Aladdin".to_owned(),
                password: Some("open sesame".to_owned()),
            })),
            path: "/service/".to_owned(),
        };

        let h: Headers<Basic> = serde_json::from_str(data).unwrap();

        assert_eq!(message, h);
    }

    #[test]
    fn de_json_bearer() {
        let data = r#"{
                        "authorization": "Bearer fpKL54jvWmEGVoRdCNjG",
                        ":path": "/service/",
                        ":method": "GET"
                      }"#;

        let message = Headers {
            authorization: Some(Authorization(
                Bearer { token: "fpKL54jvWmEGVoRdCNjG".to_owned() },
            )),
            path: "/service/".to_owned(),
        };

        let h: Headers<Bearer> = serde_json::from_str(data).unwrap();

        assert_eq!(message, h);
    }

    #[test]
    fn de_json_none() {
        let data = r#"{
                        ":path": "/service/",
                        ":method": "GET"
                      }"#;

        let message = Headers {
            authorization: None,
            path: "/service/".to_owned(),
        };

        let h: Headers<Bearer> = serde_json::from_str(data).unwrap();
        // this also works, though neither should ideally
        // let h: Headers<Basic> = serde_json::from_str(data).unwrap();

        assert_eq!(message, h);
    }
}

此字段使用Ajax Fetching,并且必须允许在创建和更新表单中使用。

任何人都可以指出我正确的方向。

1 个答案:

答案 0 :(得分:0)

我看到两个解决方案: a)创建小部件 - 更多工作,但通过添加其他设置灵活使用 b)创建单独的视图并渲染它 - 更快,但没有那么灵活