给定一个后端基于PHP或ruby的web应用程序,并且在前端使用JavaScript编程,有时我们需要在两边定义值来处理通过api在前端和后端之间通信的数据。
在JavaScript中是这样的:
var options = {
OPT_A : 1,
OPT_B : 2,
OPT_C : 3
};
switch(data.type)
{
case options.OPT_A:
/* */
break;
case options.OPT_B:
/* */
break;
case options.OPT_C:
/* */
break;
}
在php中是这样的:
const OPT_A = 1;
const OPT_B = 2;
const OPT_C = 3;
问题是你必须定义它们两次;每种语言各一次。这可能导致错误/不一致。
我想到的唯一方法是从服务器定义JavaScript部分,但我不喜欢JS代码由PHP/Ruby代码编写的想法。
有没有办法做到这一点没有代码重复?
这是一个如何创建PHP enum并将其作为对象发送到前端的解决方案。
在PHP中,我创建了一个enum类Food:
abstract class Food
{
const BANANA = 0;
const ORANGE = 1;
const WATERMELON = 2;
const BANANA_STRING = 'banana';
const ORANGE_STRING = 'orange';
const WATERMELON_STRING = 'watermelon';
const MAP = [
self::BANANA => self::BANANA_STRING,
self::ORANGE => self::ORANGE_STRING,
self::WATERMELON => self::WATERMELON_STRING
];
const REVERSEMAP = [
self::BANANA_STRING => self::BANANA,
self::ORANGE_STRING => self::ORANGE,
self::WATERMELON_STRING => self::WATERMELON
];
static function toString($enum){
return self::MAP[$enum];
}
static function toEnum($string){
return self::REVERSEMAP[$string];
}
}
我在接下来的步骤中使用Laravel框架,但根据你的项目,它应该是基本相同的。这里的重要部分是我使用了我在enum中创建的::MAP:
use PathToMyLibrary'MyLibrary'Enums'Food;
class FoodController extends Controller {
public function foodView() {
$title = "hello";
$food_enum = Food::MAP;
// attach these variables to the food view
return view('food', compact('title', 'food_enum'));
}
}
现在在我的food.blade.php文件(在Laravel中使用的PHP-html视图模板文件)中,我可以将这个$food_enum PHP对象转换为JavaScript对象。
@section('title')
{{title}}
@endsection
@section('page_content')
<div class="page-heading">
<h1>{{title}}</h1>
</div>
<div id="food-app">...your content...</div>
@endsection
@section('includes')
<script>
// convert this $food_enum from a PHP object into a JavaScript object
var food_enum = <?php echo json_encode($food_enum); ?>;
</script>
@endsection
此时,JavaScript中的对象将与PHP中的enum对象匹配。不再需要在PHP和JavaScript中维护一个冗余的枚举!
您将需要阅读有关web服务的内容。web服务本质上是一个函数。你传递给它一些参数,它会给你一些信息。通常用于允许程序访问外部数据。您几乎可以在任何API中看到它们的作用。查看stackexchange的api示例。
最小的例子:
#sinatra routing
get '/webservice/test' do
content_type :json
data = {options: {
opt_a: 1,
opt_b: 2,
opt_c: 3
}}
JSON.pretty_generate(data)
end
所以,当你访问your-site.com/webservice/test
时,你会得到:
{
"options": {
"opt_a": 1,
"opt_b": 2,
"opt_c": 3
}
}
在javascript中使用这些数据变得微不足道:
var call = new XMLHttpRequest();
call.onreadystatechange = function() {
if(call.readyState == XMLHttpRequest.DONE) {
if(call.status == 200) {
obj = JSON.parse(call.responseText);
console.log(obj);
} else if(xmlhttp.status == 400) {
console.log("error 400");
} else {
alert("some other thing happened");
}
}
}
call.open("GET", "/webservice/test", true);
call.send();
现在您的数据已经在客户端了!具体来说,obj
将是Object {options: Object}
,因此您将使用obj.options.opt_a
访问您的3个选项以获得1
。
这里有一些关于webservice的简明英语解释。
如果您不熟悉http响应代码,您可以查看这里的完整列表。这是javascript代码的call.status
部分。
如果你愿意,你可以用jQuery用$.getJSON("/webservice/test", function() ...)
做同样的ajax调用。你可以在这里阅读更多信息
在我的项目中,我在API上创建一个端点,返回json中的enum。然后,我用redux存储它,以免每次访问页面时都要调用它。如果你不使用JS框架,你仍然可以创建一个由ajax请求触发的url,并提供你的javascript。你也可以创建一个json文件,存储在公共目录中,然后导入到javascript中,然后使用后端语言