使用 JavaScript 显示 Laravel 的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29308441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:08:59  来源:igfitidea点击:

Using JavaScript to display Laravel's Variable

javascriptphplaravellaravel-5laravel-blade

提问by Sylar

In my code I am using typeahead.js. I use Laravel 5 and I need to replace the var stateswith my {{ $jobs }}variable. I need to list all Job Titles as an array.

在我的代码中,我使用typeahead.js。我使用 Laravel 5,我需要var states用我的{{ $jobs }}变量替换。我需要将所有职位列为一个数组。

In my controller I have

在我的控制器中,我有

$jobs = Job::all(['job_title']);

I know the loop method in javascript but I dont know how to "link" my blade's variable in the javascript. Anyone knows how to?

我知道 javascript 中的循环方法,但我不知道如何在 javascript 中“链接”我的刀片变量。有谁知道怎么做?

I have tried, in my.js

我试过了,在 my.js

var jobs = {{ $jobs }}

But that wont work.

但这行不通。

回答by lukasgeiter

For more complex variable types like arrays your best bet is to convert it into JSON, echo that in your template and decode it in JavaScript. Like this:

对于更复杂的变量类型,如数组,最好的办法是将其转换为 JSON,在模板中回显并在 JavaScript 中解码。像这样:

var jobs = JSON.parse("{{ json_encode($jobs) }}");


Note that PHP has to run over this code to make it work. In this case you'd have to put it inside your Blade template. If you have your JavaScript code in one or more separate files (which is good!) you can just add an inline script tag to your template where you pass your variables. (Just make sure that it runs beforethe rest of your JavaScript code. Usually document.readyis the answer to that)

请注意,PHP 必须运行此代码才能使其工作。在这种情况下,您必须将其放入 Blade 模板中。如果您将 JavaScript 代码保存在一个或多个单独的文件中(这很好!),您只需将内联脚本标记添加到您传递变量的模板中即可。(只要确保它您的 JavaScript 代码的其余部分之前运行。通常document.ready是答案)

<script>
    var jobs = JSON.parse("{{ json_encode($jobs) }}");
</script>

If you don't like the idea of doing it like this I suggest you fetch the data in a separate ajax request.

如果您不喜欢这样做的想法,我建议您在单独的 ajax 请求中获取数据。

回答by Karim Samir

This works for me

这对我有用

jobs = {!! json_encode($jobs) !!};

回答by Jimmy Obonyo Abor

Just to add to above :

只是添加到上面:

var jobs = JSON.parse("{{ json_encode($jobs) }}");

var jobs = JSON.parse("{{ json_encode($jobs) }}");

will return escaped html entities ,hence you will not be able to loop over the json object in javascript , to solve this please use below :

将返回转义的 html 实体,因此您将无法在 javascript 中循环遍历 json 对象,要解决此问题,请在下面使用:

var jobs = JSON.parse("{!! json_encode($jobs) !!}");

var jobs = JSON.parse("{!! json_encode($jobs) !!}");

or

或者

var jobs = JSON.parse(<?php echo json_encode($jobs); ?>);

var jobs = JSON.parse(<?php echo json_encode($jobs); ?>);

回答by Jignesh Joisar

in laravel 6this works for me

laravel 6这对我有用

using laravel blade directive

使用 Laravel 刀片指令

var jobs = {!! json_encode($jobs) !!};

also used @jsondirective

也使用@json指令

var jobs = @json($jobs);

using php style

使用 php 风格

 var jobs = <?php echo json_encode($jobs); ?>

回答by behnam shateri

this approach work for me:

这种方法对我有用:

var job = {!! json_encode($jobs ) !!}

and use in java script

并在java脚本中使用

回答by agm1984

I just solved this by placing a reference on the windowObject in the <head>of my layout file, and then picking that reference up with a mixin that can be injected into any component.

我只是通过window<head>我的布局文件的对象上放置一个引用来解决这个问题,然后使用可以注入任何组件的 mixin 选择该引用。

TLDR SOLUTION

解决方案

.env

.env

GEODATA_URL="https://geo.some-domain.com"

config/geodata.php

配置/地理数据.php

<?php

return [
    'url' => env('GEODATA_URL')
];

resources/views/layouts/root.blade.php

资源/视图/布局/root.blade.php

<head>
    <script>
        window.geodataUrl = "{{ config('geodata.url') }}";
    </script>
</head>

resources/js/components/mixins/geodataUrl.js

资源/js/components/mixins/geodataUrl.js

const geodataUrl = {
    data() {
        return {
            geodataUrl: window.geodataUrl,
        };
    },
};

export default geodataUrl;

usage

用法

<template>
    <div>
        <a :href="geodataUrl">YOLO</a>
    </div>
</template>

<script>
import geodataUrl from '../mixins/geodataUrl';

export default {
    name: 'v-foo',

    mixins: [geodataUrl],

    data() {
        return {};
    },

    computed: {},

    methods: {},
};
</script>

END TLDR SOLUTION

结束 TLDR 解决方案

If you want, you can use a global mixin instead by adding this to your app.jsentrypoint:

如果需要,您可以通过将其添加到app.js入口点来使用全局混合:

Vue.mixin({
    data() {
        return {
            geodataUrl: window.geodataUrl,
        };
    },
});

I would not recommend using this pattern, however, for any sensitive data because it is sitting on the windowObject.

但是,我不建议对任何敏感数据使用此模式,因为它位于window对象上。

I like this solution because it doesn't use any extra libraries, and the chain of code is very clear. It passes the grep test, in that you can search your code for "window.geodataUrl"and see everything you need to understand how and why the code is working.

我喜欢这个解决方案,因为它不使用任何额外的库,而且代码链非常清晰。它通过了 grep 测试,因为您可以搜索代码"window.geodataUrl"并查看了解代码工作方式和原因所需的一切。

That consideration is important if the code may live for a long time and another developer may come across it.

如果代码可能存在很长时间并且其他开发人员可能会遇到它,那么这种考虑很重要。

However, JavaScript::put([])is in my opinion, a decent utility that can be worth having, but in the past I have disliked how it can be extremely difficult to debug if a problem happens, because you cannot see where in the codebase the data comes from.

然而,JavaScript::put([])在我看来,这是一个值得拥有的不错的实用程序,但在过去,我不喜欢如果出现问题,调试会非常困难,因为您看不到代码库中数据的来源。

Imagine you have some Vue code that is consuming window.chartDatathat came from JavaScript::put([ 'chartData' => $user->chartStuff ]). Depending on the number of references to chartDatain your code base, it could take you a very long time to discover which PHP file was responsible for making window.chartDatawork, especially if you didn't write that code and the next person has no idea JavaScript::put()is being used.

想象一下,您有一些window.chartData来自JavaScript::put([ 'chartData' => $user->chartStuff ]). 根据chartData您的代码库中引用的数量,您可能需要很长时间才能发现哪个 PHP 文件负责使window.chartData工作,特别是如果您没有编写该代码并且下一个人不知道JavaScript::put()正在使用.

In that case, I recommend putting a comment in the code like:

在这种情况下,我建议在代码中添加注释,例如:

/* data comes from poop.php via JavaScript::put */

Then the person can search the code for "JavaScript::put"and quickly find it. Keep in mind "the person" could be yourself in 6 months after you forget the implementation details.

然后这个人可以搜索代码"JavaScript::put"并快速找到它。请记住,在您忘记实施细节后的 6 个月内,“人”可能就是您自己。

It is always a good idea to use Vue component prop declarations like this:

像这样使用 Vue 组件 prop 声明总是一个好主意:

props: {
    chartData: {
        type: Array,
        required: true,
    },
},

My point is, if you use JavaScript::put(), then Vue cannot detect as easily if the component fails to receive the data. Vue must assume the data is there on the window Object at the moment in time it refers to it. Your best bet may be to instead create a GET endpoint and make a fetch call in your created/mounted lifecycle method.

我的观点是,如果您使用JavaScript::put(),那么 Vue 无法轻松检测到组件是否无法接收数据。Vue 必须假设数据在它引用它的那一刻就在 window 对象上。您最好的选择可能是创建一个 GET 端点并在您创建/安装的生命周期方法中进行 fetch 调用。

I think it is important to have an explicit contract between Laravel and Vue when it comes to getting/setting data.

我认为在获取/设置数据时,在 Laravel 和 Vue 之间制定明确的合同很重要。

In the interest of helping you as much as possible by giving you options, here is an example of making a fetch call using ES6 syntax sugar:

为了通过为您提供选项来尽可能多地帮助您,以下是使用 ES6 语法糖进行 fetch 调用的示例:

routes/web.php

路线/ web.php

Route::get('/charts/{user}/coolchart', 'UserController@getChart')->name('user.chart');

app/Http/Controllers/UserController.php

应用程序/Http/Controllers/UserController.php

public function getChart(Request $request, User $user)
{
    // do stuff
    $data = $user->chart;

    return response()->json([
        'chartData' => $data,
    ]);
}

Anywhere in Vue, especially a created lifecycle method:

Vue 中的任何地方,尤其是创建的生命周期方法:

created() {
    this.handleGetChart();
},

methods: {
    async handleGetChart() {
        try {
            this.state = LOADING;
            const { data } = await axios.get(`/charts/${this.user.id}/coolchart`);

            if (typeof data !== 'object') {
                throw new Error(`Unexpected server response. Expected object, got: ${data}`);
            }

            this.chartData = data.chartData;
            this.state = DATA_LOADED;
        } catch (err) {
            this.state = DATA_FAILED;
            throw new Error(`Problem getting chart data: ${err}`);
        }
    },
},

That example assumes your Vue component is a Mealy finite state machine, whereby the component can only be in one state at any given time, but it can freely switch between states.

该示例假设您的 Vue 组件是一个 Mealy 有限状态机,即该组件在任何给定时间只能处于一种状态,但它可以在状态之间自由切换。

I'd recommend using such states as computed props:

我建议使用这样的状态作为计算道具:

computed: {
    isLoading() { return (this.state === LOADING); },
    isDataLoaded() { return (this.state === DATA_LOADED); },
    isDataFailed() { return (this.state === DATA_FAILED); },
},

With markup such as:

带有标记,例如:

<div v-show="isLoading">Loading...</div>
<v-baller-chart v-if="isDataLoaded" :data="chartData"></v-baller-chart>
<button v-show="isDataFailed" type="button" @click="handleGetChart">TRY AGAIN</button>