在 Laravel 4 的 .find jquery 行中使用辅助函数
Posted
技术标签:
【中文标题】在 Laravel 4 的 .find jquery 行中使用辅助函数【英文标题】:Using a helper function in a .find jquery line in Laravel 4 【发布时间】:2013-08-08 04:53:01 【问题描述】:我在 Laravel 4 中设置了一个帮助函数,用于将时间戳转换为可读日期。该函数在文件 StringEdit.php 中称为“getDate”(在文件夹“helpers”中)。我知道这个功能有效。
我正在尝试在 jquery 调用中使用此函数,该调用从数据库中获取数据并将其加载到 div id(每次单击时加载更多数据)。代码如下:
<script type="text/javascript">
$(function()
<?php $number_of_posts = 2; ?>;
<?php $_SESSION['posts_start'] = isset($_SESSION['posts_start']) ? $_SESSION['posts_start'] : $number_of_posts; ?>;
//<?php $_SESSION['posts_start'] = $_SESSION['posts_start'] ? $_SESSION['posts_start'] : $number_of_posts; ?>;
//<?php $_SESSION['posts_start'] = 2 ?>;
//var start = <?php echo $_SESSION['posts_start']; ?>;
var start = Session::get('posts_start', 2) ;
var initialPosts = <?php echo Fanartist::friend_activity_json(0, $_SESSION['posts_start']); ?>;
//var initialPosts = <?php echo Fanartist::friend_activity_json(0, 2); ?>;
var desiredPosts = <?php echo $number_of_posts; ?>;
var template = '<tr>'
+'<td>'
+'<div class="friend_image">'
+'<img src="https://graph.facebook.com/fbid/picture" class="img-rounded">'
+'</div>'
+'</td>'
+'<td>'
+'<div class="friend_activity">'
+'<span class="activity_text"><span class="first_name"></span> <span class="last_name"></span> indicated that <span class="gender"></span> wants <a href="/artists/artist_id"><span class="stage_name"></span></a> to come to <span class="city"></span></span>'
+'<br><span class="activity_subtext"><span class="created_at"></span></span>'
+'</div>'
+'</td>'
+'</tr>';
var activity = $('#activity'),
// Element to load the posts
content = activity.find('.content'),
// the more button
more = activity.find('.more'),
// the post counter
counter = activity.find('.badge');
// Create alerts elements (Display Success or Failure)
var alerts =
requestEmpty : $('<div class="alert alert-info">No more data</div>'),
requestFailure : $('<div class="alert alert-error">Could not get the data. Try again!</div>')
var progressElement = $('<div class="progress" style="margin-bottom:0"><div class="bar"></div></div>');
var progressBar = progressElement.find('.bar');
var postHandler = function(posts)
// Set the progress bar to 100%
progressBar.css('width', '100%');
// Delay the normal more button to come back for a better effect
window.setTimeout(function()more.html('More <span class="caret"></span>'), 500);
// insert childrens at the end of the content element
for (post in posts)
// Clone the element
var $post = $(template).clone();
$post.attr('id', 'post-' + posts[post].ID);
var $img = $post.find('div.friend_image').find('img');
$img.attr('src', $img.attr('src').replace('fbid', posts[post].fbid));
$img.attr('alt', posts[post].first_name);
var $spantext = $post.find('div.friend_activity').find('span.activity_text');
$spantext.html($spantext.html().replace('artist_id', posts[post].artist_id));
//$post.find('.fbid').html(posts[post].fbid);
$post.find('.first_name').html(posts[post].first_name);
$post.find('.last_name').html(posts[post].last_name);
$post.find('.city').html(posts[post].city);
$post.find('.gender').html(posts[post].gender == 'male' ? 'he' : 'she');
//$post.find('.artist_id').html(posts[post].artist_id);
$post.find('.stage_name').html(posts[post].stage_name);
$post.find('.created_at').html(posts[post].created_at);
content.append($post);
content.animate(
scrollTop: $('#post-' + posts[0].ID).offset().top + (content.scrollTop()- content.offset().top)
, 200);
// place the initial posts in the page
postHandler(initialPosts);
// add the click event to the more button
more.click(function()
// Set the progress bar to 0%
progressBar.css('width', '0%');
// remove the more button innerHTML and insert the progress bar
more.empty().append(progressElement);
// AJAX REQUEST
$.ajax(
url: "http://crowdtest.dev:8888/fans/setup_widget",
type: 'GET',
// We do not want IE to cache the result
cache: false,
data:
'start': start,
'desiredPosts': desiredPosts
).success(function (data, text)
// parse the response (typeof data == String)
data = JSON.parse(data);
if (data.length > 0)
// Update the total number of items
start += data.length;
// Update the counter
counter.html(start);
// load items on the page
postHandler(data);
else
$alert = alerts.requestEmpty;
// insert the empty message
activity.prepend($alert);
// Set the progress bar to 100%
progressBar.css('width', '100%');
// Remove the more button
window.setTimeout(function()more.remove(), 500);
// remove the empty message after 4 seconds
window.setTimeout(function()$alert.remove(), 4000);
).error(function (request, status, error)
$alert = alerts.requestFailure;
// insert the failure message
activity.prepend($alert);
// Set the progress bar to 100%
progressBar.css('width', '100%');
// Delay the normal more button to come back for a better effect
window.setTimeout(function()more.html('More <span class="caret"></span>'), 500);
);
);
console.log(desiredPosts);
console.log(start);
console.log(initialPosts);
);
</script>
在 html 中使用 div id "activity" 调用:
<div id="activity">
<table class="table table-striped">
<thead>
<tr>
<th><div class="friend_image"></div></th>
<th><div class="friend_activity"></div></th>
</tr>
</thead>
<tbody class="content">
</tbody>
</table>
<button class="more btn btn-block">
More <span class="caret"></span>
</button>
</div>
一切都正确输出,除了 created_at 部分。我得到了错误:
SyntaxError: missing ) after argument list
引用行:
$post.find('.created_at').html(posts[post].StringEdit::getDate(created_at));
你知道我将如何调用这个函数来编辑 jquery 中数据库中的 created_at 实体吗?感谢您的帮助。
【问题讨论】:
你能解释一下你在这里做什么吗?$post.find('.created_at').html(posts[post].StringEdit::getDate(created_at));
你是如何尝试从 javascript 中调用 PHP 类和函数的?
好吧,我知道这是错误的,但我不知道该怎么做...我想用那个 PHP 类和函数更改 jquery 中返回的值。
是.js文件还是blade.php文件上的第一个代码sn-p?我可以就此提出建议。
posts变量是通过jquery ajax绑定的吗?
它在刀片文件本身中。而post变量是通过ajax绑定的。
【参考方案1】:
你为什么不在数据库中的 eloquent 模型上使用 Accessor,所以你甚至根本不需要 getDate() 函数?
class User extends Eloquent
public function getCreatedAt($value)
// created_at will now be formatted as "d-m-Y"
return date('d-m-Y', strtotime($value));
只需将 date() 函数格式更改为您需要的任何格式(即与您的 getDate() 函数格式相同)
【讨论】:
问题是我不希望这个字段一直以这种方式改变,我只想在这个特定的实例中改变它。 有没有办法让这个访问器只影响某些查询? 您可以创建一个虚拟访问器 getFormattedCreatedAt($value) 并根据具体情况调用真实字段 getCreatedAt 的“普通”访问器或其他访问器 getFormattedCreatedAt 来访问预处理的“虚拟”数据. 你能在你的答案中添加一个这样的代码示例吗?我在执行此操作时遇到了问题。【参考方案2】:根据您的回复,关于传递给刀片模板的变量,您写道您提供的 javascript 代码 - “它在刀片文件本身中。并且 post 变量通过 ajax 绑定。” 我想解决方案很简单——你可以只用刀片和 php 来满足你的需求,而不需要 JS(在你的情况下这是多余的)
在你的 laravel 控制器中 1)将 $posts 变量传递给视图(而不是返回它,显示或任何你的模板实现)
View::make('posts', $posts);
在您的刀片模板中 1) 像你已经做的那样将帖子变量提供给模板 2) 将您在 javascript 中的“模板”变量构造为刀片模板 php 代码 3)使用blade给变量填充数据(而不是像现在这样用JS解析模板代码)
下面的一些例子(只是一个 sn-p):
// app/views/posts.blade.php
-- this is a blade comment --
<div id="activity">
<table class="table table-striped">
<thead>
<tr>
<th><div class="friend_image"></div></th>
<th><div class="friend_activity"></div></th>
</tr>
</thead>
<tbody class="content">
-- in the below foreach loop you put the html you currently have in javascript template variable var template; --
@foreach ($posts as $post)
-- inside the foreach loop you have access to all your $posts, so while iterating you can do: --
-- 1) access $post fields --
$post->id
$post->fbid
$post->whatever
-- 2) access $post fields and apply function on them --
StringEdit::getDate($post->whatever)
@endforeach
</tbody>
</table>
<button class="more btn btn-block">
More <span class="caret"></span>
</button>
</div>
如果您按照建议进行操作,您就不必将 Php 错误地处理为 Javascript 问题,而且它看起来确实是解决您问题的更清洁、更简单的方法。当然你会得到你所要求的——你将能够在模板中使用字符串辅助函数:)
编辑: 我更新了上面的帖子以包含来自 cmets 的讨论信息
编辑 2: 回答 cmets 的后续请求:
使用自定义 Eloquent 模型访问器
假设你的模型中有一个字段(datacolumn)(当然是用来表示数据库中的一个表),这个字段的名字是MyFancyField。现在,对于您的系统,您需要有可能获取预处理过的该字段的内容 - 您需要它是大写的。因此,您可以创建一个如下所示的自定义访问器并引用它(使用它),就像它是模型的另一个字段一样。
模型:/app/models/Book.php
class Book extends Eloquent
protected $table = 'books';
public function toArray()
$array = parent::toArray();
foreach ($this->getMutatedAttributes() as $key)
if ( ! array_key_exists($key, $array))
$array[$key] = $this->$key;
return $array;
public function getUpperMyFancyField()
return strtoupper($this->myFancyField);
控制器:/app/controllers/
public function index(Book $book)
$this->book = $book;
echo "The original field fetched by a default accessor: " . $this->book->myFancyField;
echo "The uppercased field fetched by another custom accessor: " . $this->book->upperMyFancyField;
只是为了记录,toArray() 是故意重载的,因为 Laravel 4 默认情况下不将“自定义访问器字段”作为数组包含到返回的对象中。所以如果你没有那个,并且想要 $this->book->toArray() 它不会在其中包含 upperMyFancyField。
【讨论】:
有什么办法可以在 javascript 完好无损的情况下做到这一点?唯一的问题是我想保持“加载更多”功能,它只在单击按钮时显示更多数据。 另外,当我这样做时,我收到错误“未定义的变量帖子”;您能否展示我如何在 javascript 中声明帖子以允许我在 foreach 循环中使用它? foreach 循环是 php-ish 循环而不是 javascript。我的提议背后的整个想法是使用 PHP 而不是 Javascript 来处理服务器端。根据您的问题,您必须将 $posts 变量从控制器传递给模板才能使用它( View::make('posts', $posts); ) 好的,问题是我希望它具有“加载更多”功能,并且我的模型中有一个函数,它需要两个变量:friend_activity_json($start, $number_of_posts)。当我在创建视图时尝试将其包含在带有控制器的页面中时,它说我提供了一个无效的参数。 你的accessor解决方案更符合我想做的。你能解释一下吗?我想保持 javascript 原样。以上是关于在 Laravel 4 的 .find jquery 行中使用辅助函数的主要内容,如果未能解决你的问题,请参考以下文章